blob: 1e39ca794cc73e925ddf8ad9de23545b8eaa5536 [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 Bauman19bac1e2014-05-06 15:23:49 -040035 Vector4f VertexPipeline::transformBlend(Registers &r, Register &src, 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
65 index0[i] = (indices & UInt(0x000000FF)) << UInt(6); // FIXME: (indices & 0x000000FF) << 6
66 index1[i] = (indices & UInt(0x0000FF00)) >> UInt(2);
67 index2[i] = (indices & UInt(0x00FF0000)) >> UInt(10);
68 index3[i] = (indices & UInt(0xFF000000)) >> UInt(18);
69 }
70 }
71 else
72 {
73 for(int i = 0; i < 4; i++)
74 {
75 index0[i] = Int(0 * 64); // FIXME: index0 = 0 * 64;
76 index1[i] = Int(1 * 64); // FIXME: index1 = 1 * 64;
77 index2[i] = Int(2 * 64); // FIXME: index2 = 2 * 64;
78 index3[i] = Int(3 * 64); // FIXME: index3 = 3 * 64;
79 }
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
175 if(state.vertexNormalActive)
176 {
177 normal = transformBlend(r, r.v[Normal], Pointer<Byte>(r.data + OFFSET(DrawData,ff.normalTransformT)), false);
178
179 if(state.normalizeNormals)
180 {
181 normal = normalize(normal);
182 }
183 }
184
185 if(!state.vertexLightingActive)
186 {
187 // FIXME: Don't process if not used at all
188 if(state.diffuseActive && state.input[Color0])
189 {
John Bauman19bac1e2014-05-06 15:23:49 -0400190 Vector4f diffuse = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400191
John Bauman19bac1e2014-05-06 15:23:49 -0400192 r.o[D0].x = diffuse.x;
193 r.o[D0].y = diffuse.y;
194 r.o[D0].z = diffuse.z;
195 r.o[D0].w = diffuse.w;
John Bauman89401822014-05-06 15:04:28 -0400196 }
197 else
198 {
John Bauman19bac1e2014-05-06 15:23:49 -0400199 r.o[D0].x = Float4(1.0f);
200 r.o[D0].y = Float4(1.0f);
201 r.o[D0].z = Float4(1.0f);
202 r.o[D0].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400203 }
204
205 // FIXME: Don't process if not used at all
206 if(state.specularActive && state.input[Color1])
207 {
John Bauman19bac1e2014-05-06 15:23:49 -0400208 Vector4f specular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400209
John Bauman19bac1e2014-05-06 15:23:49 -0400210 r.o[D1].x = specular.x;
211 r.o[D1].y = specular.y;
212 r.o[D1].z = specular.z;
213 r.o[D1].w = specular.w;
John Bauman89401822014-05-06 15:04:28 -0400214 }
215 else
216 {
John Bauman19bac1e2014-05-06 15:23:49 -0400217 r.o[D1].x = Float4(0.0f);
218 r.o[D1].y = Float4(0.0f);
219 r.o[D1].z = Float4(0.0f);
220 r.o[D1].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400221 }
222 }
223 else
224 {
John Bauman19bac1e2014-05-06 15:23:49 -0400225 Vector4f diffuseSum;
John Bauman89401822014-05-06 15:04:28 -0400226
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
John Bauman19bac1e2014-05-06 15:23:49 -0400237 diffuseSum.x = Float4(0.0f);
238 diffuseSum.y = Float4(0.0f);
239 diffuseSum.z = Float4(0.0f);
240 diffuseSum.w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400241
John Bauman19bac1e2014-05-06 15:23:49 -0400242 Vector4f vertexPosition = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
John Bauman89401822014-05-06 15:04:28 -0400243
244 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
John Bauman19bac1e2014-05-06 15:23:49 -0400284 r.o[D0].x = r.o[D0].x + lightAmbient.x * att;
285 r.o[D0].y = r.o[D0].y + lightAmbient.y * att;
286 r.o[D0].z = r.o[D0].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
300 if(state.vertexDiffuseMaterialSourceActive == Context::MATERIAL)
301 {
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 }
307 else if(state.vertexDiffuseMaterialSourceActive == Context::COLOR1)
308 {
309 diff = r.v[Color0];
310 }
311 else if(state.vertexDiffuseMaterialSourceActive == Context::COLOR2)
312 {
313 diff = r.v[Color1];
314 }
315 else ASSERT(false);
316
317 Float4 lightDiffuse = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightDiffuse[i]));
318
319 diffuseSum.x += diff.x * dot * lightDiffuse.x; // FIXME: Clamp first?
320 diffuseSum.y += diff.y * dot * lightDiffuse.y; // FIXME: Clamp first?
321 diffuseSum.z += diff.z * dot * lightDiffuse.z; // FIXME: Clamp first?
322 }
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
350 if(state.vertexSpecularMaterialSourceActive == Context::MATERIAL)
351 {
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 }
358 else if(state.vertexSpecularMaterialSourceActive == Context::COLOR1)
359 {
360 spec = r.v[Color0];
361 }
362 else if(state.vertexSpecularMaterialSourceActive == Context::COLOR2)
363 {
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
388 Float4 globalAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.globalAmbient)); // FIXME: Unpack
389
John Bauman19bac1e2014-05-06 15:23:49 -0400390 r.o[D0].x = r.o[D0].x + globalAmbient.x;
391 r.o[D0].y = r.o[D0].y + globalAmbient.y;
392 r.o[D0].z = r.o[D0].z + globalAmbient.z;
John Bauman89401822014-05-06 15:04:28 -0400393
394 if(state.vertexAmbientMaterialSourceActive == Context::MATERIAL)
395 {
396 Float4 materialAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialAmbient)); // FIXME: Unpack
397
John Bauman19bac1e2014-05-06 15:23:49 -0400398 r.o[D0].x = r.o[D0].x * materialAmbient.x;
399 r.o[D0].y = r.o[D0].y * materialAmbient.y;
400 r.o[D0].z = r.o[D0].z * materialAmbient.z;
John Bauman89401822014-05-06 15:04:28 -0400401 }
402 else if(state.vertexAmbientMaterialSourceActive == Context::COLOR1)
403 {
John Bauman19bac1e2014-05-06 15:23:49 -0400404 Vector4f materialDiffuse = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400405
John Bauman19bac1e2014-05-06 15:23:49 -0400406 r.o[D0].x = r.o[D0].x * materialDiffuse.x;
407 r.o[D0].y = r.o[D0].y * materialDiffuse.y;
408 r.o[D0].z = r.o[D0].z * materialDiffuse.z;
John Bauman89401822014-05-06 15:04:28 -0400409 }
410 else if(state.vertexAmbientMaterialSourceActive == Context::COLOR2)
411 {
John Bauman19bac1e2014-05-06 15:23:49 -0400412 Vector4f materialSpecular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400413
John Bauman19bac1e2014-05-06 15:23:49 -0400414 r.o[D0].x = r.o[D0].x * materialSpecular.x;
415 r.o[D0].y = r.o[D0].y * materialSpecular.y;
416 r.o[D0].z = r.o[D0].z * materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400417 }
418 else ASSERT(false);
419
John Bauman19bac1e2014-05-06 15:23:49 -0400420 r.o[D0].x = r.o[D0].x + diffuseSum.x;
421 r.o[D0].y = r.o[D0].y + diffuseSum.y;
422 r.o[D0].z = r.o[D0].z + diffuseSum.z;
John Bauman89401822014-05-06 15:04:28 -0400423
424 // Emissive
425 if(state.vertexEmissiveMaterialSourceActive == Context::MATERIAL)
426 {
427 Float4 materialEmission = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialEmission)); // FIXME: Unpack
428
John Bauman19bac1e2014-05-06 15:23:49 -0400429 r.o[D0].x = r.o[D0].x + materialEmission.x;
430 r.o[D0].y = r.o[D0].y + materialEmission.y;
431 r.o[D0].z = r.o[D0].z + materialEmission.z;
John Bauman89401822014-05-06 15:04:28 -0400432 }
433 else if(state.vertexEmissiveMaterialSourceActive == Context::COLOR1)
434 {
John Bauman19bac1e2014-05-06 15:23:49 -0400435 Vector4f materialSpecular = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400436
John Bauman19bac1e2014-05-06 15:23:49 -0400437 r.o[D0].x = r.o[D0].x + materialSpecular.x;
438 r.o[D0].y = r.o[D0].y + materialSpecular.y;
439 r.o[D0].z = r.o[D0].z + materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400440 }
441 else if(state.vertexEmissiveMaterialSourceActive == Context::COLOR2)
442 {
John Bauman19bac1e2014-05-06 15:23:49 -0400443 Vector4f materialSpecular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400444
John Bauman19bac1e2014-05-06 15:23:49 -0400445 r.o[D0].x = r.o[D0].x + materialSpecular.x;
446 r.o[D0].y = r.o[D0].y + materialSpecular.y;
447 r.o[D0].z = r.o[D0].z + materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400448 }
449 else ASSERT(false);
450
451 // Diffuse alpha component
452 if(state.vertexDiffuseMaterialSourceActive == Context::MATERIAL)
453 {
John Bauman19bac1e2014-05-06 15:23:49 -0400454 r.o[D0].w = Float4(*Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialDiffuse[0]))).wwww; // FIXME: Unpack
John Bauman89401822014-05-06 15:04:28 -0400455 }
456 else if(state.vertexDiffuseMaterialSourceActive == Context::COLOR1)
457 {
John Bauman19bac1e2014-05-06 15:23:49 -0400458 Vector4f alpha = r.v[Color0];
459 r.o[D0].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400460 }
461 else if(state.vertexDiffuseMaterialSourceActive == Context::COLOR2)
462 {
John Bauman19bac1e2014-05-06 15:23:49 -0400463 Vector4f alpha = r.v[Color1];
464 r.o[D0].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400465 }
466 else ASSERT(false);
467
468 if(state.vertexSpecularActive)
469 {
470 // Specular alpha component
471 if(state.vertexSpecularMaterialSourceActive == Context::MATERIAL)
472 {
John Bauman19bac1e2014-05-06 15:23:49 -0400473 r.o[D1].w = Float4(*Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialSpecular[3]))).wwww; // FIXME: Unpack
John Bauman89401822014-05-06 15:04:28 -0400474 }
475 else if(state.vertexSpecularMaterialSourceActive == Context::COLOR1)
476 {
John Bauman19bac1e2014-05-06 15:23:49 -0400477 Vector4f alpha = r.v[Color0];
478 r.o[D1].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400479 }
480 else if(state.vertexSpecularMaterialSourceActive == Context::COLOR2)
481 {
John Bauman19bac1e2014-05-06 15:23:49 -0400482 Vector4f alpha = r.v[Color1];
483 r.o[D1].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400484 }
485 else ASSERT(false);
486 }
487 }
488
489 if(state.fogActive)
490 {
491 switch(state.vertexFogMode)
492 {
493 case Context::FOG_NONE:
494 if(state.specularActive)
495 {
John Bauman19bac1e2014-05-06 15:23:49 -0400496 r.o[Fog].x = r.o[D1].w;
John Bauman89401822014-05-06 15:04:28 -0400497 }
498 else
499 {
John Bauman19bac1e2014-05-06 15:23:49 -0400500 r.o[Fog].x = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400501 }
502 break;
503 case Context::FOG_LINEAR:
504 case Context::FOG_EXP:
505 case Context::FOG_EXP2:
506 if(!state.rangeFogActive)
507 {
John Bauman19bac1e2014-05-06 15:23:49 -0400508 r.o[Fog].x = r.o[Pos].z;
John Bauman89401822014-05-06 15:04:28 -0400509 }
510 else
511 {
John Bauman19bac1e2014-05-06 15:23:49 -0400512 Vector4f pos;
John Bauman89401822014-05-06 15:04:28 -0400513
John Bauman19bac1e2014-05-06 15:23:49 -0400514 pos.x = r.o[Pos].x;
515 pos.y = r.o[Pos].y;
516 pos.z = r.o[Pos].z;
517 pos.w = r.o[Pos].w;
John Bauman89401822014-05-06 15:04:28 -0400518
John Bauman19bac1e2014-05-06 15:23:49 -0400519 r.o[Fog].x = Sqrt(dot3(pos, pos)); // FIXME: oFog = length(o[Pos]);
John Bauman89401822014-05-06 15:04:28 -0400520 }
521
John Bauman19bac1e2014-05-06 15:23:49 -0400522 r.o[Fog].x = r.o[Fog].x * *Pointer<Float4>(r.data + OFFSET(DrawData,fog.scale)) + *Pointer<Float4>(r.data + OFFSET(DrawData,fog.offset));
John Bauman89401822014-05-06 15:04:28 -0400523 break;
524 default:
525 ASSERT(false);
526 }
527 }
528
529 for(int stage = 0; stage < 8; stage++)
530 {
531 processTextureCoordinate(r, stage, normal, position);
532 }
533
534 processPointSize(r);
535 }
536
John Bauman19bac1e2014-05-06 15:23:49 -0400537 void VertexPipeline::processTextureCoordinate(Registers &r, int stage, Vector4f &normal, Vector4f &position)
John Bauman89401822014-05-06 15:04:28 -0400538 {
539 if(state.output[T0 + stage].write)
540 {
541 int i = state.textureState[stage].texCoordIndexActive;
542
543 switch(state.textureState[stage].texGenActive)
544 {
545 case Context::TEXGEN_PASSTHRU:
546 {
John Bauman19bac1e2014-05-06 15:23:49 -0400547 Vector4f v = r.v[TexCoord0 + i];
John Bauman89401822014-05-06 15:04:28 -0400548
John Bauman19bac1e2014-05-06 15:23:49 -0400549 r.o[T0 + stage].x = v.x;
550 r.o[T0 + stage].y = v.y;
551 r.o[T0 + stage].z = v.z;
552 r.o[T0 + stage].w = v.w;
John Bauman89401822014-05-06 15:04:28 -0400553
John Bauman19bac1e2014-05-06 15:23:49 -0400554 if(state.input[TexCoord0 + i])
John Bauman89401822014-05-06 15:04:28 -0400555 {
556 switch(state.input[TexCoord0 + i].count)
557 {
558 case 1:
John Bauman19bac1e2014-05-06 15:23:49 -0400559 r.o[T0 + stage].y = Float4(1.0f);
560 r.o[T0 + stage].z = Float4(0.0f);
561 r.o[T0 + stage].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400562 break;
563 case 2:
John Bauman19bac1e2014-05-06 15:23:49 -0400564 r.o[T0 + stage].z = Float4(1.0f);
565 r.o[T0 + stage].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400566 break;
567 case 3:
John Bauman19bac1e2014-05-06 15:23:49 -0400568 r.o[T0 + stage].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400569 break;
570 case 4:
571 break;
572 default:
573 ASSERT(false);
574 }
575 }
John Bauman89401822014-05-06 15:04:28 -0400576 }
577 break;
578 case Context::TEXGEN_NORMAL:
579 {
John Bauman19bac1e2014-05-06 15:23:49 -0400580 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400581
582 if(state.vertexNormalActive)
583 {
584 Nc = normal;
585 }
586 else
587 {
John Bauman19bac1e2014-05-06 15:23:49 -0400588 Nc.x = Float4(0.0f);
589 Nc.y = Float4(0.0f);
590 Nc.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400591 }
592
John Bauman19bac1e2014-05-06 15:23:49 -0400593 Nc.w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400594
John Bauman19bac1e2014-05-06 15:23:49 -0400595 r.o[T0 + stage].x = Nc.x;
596 r.o[T0 + stage].y = Nc.y;
597 r.o[T0 + stage].z = Nc.z;
598 r.o[T0 + stage].w = Nc.w;
John Bauman89401822014-05-06 15:04:28 -0400599 }
600 break;
601 case Context::TEXGEN_POSITION:
602 {
John Bauman19bac1e2014-05-06 15:23:49 -0400603 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 -0400604
John Bauman19bac1e2014-05-06 15:23:49 -0400605 Pn.w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400606
John Bauman19bac1e2014-05-06 15:23:49 -0400607 r.o[T0 + stage].x = Pn.x;
608 r.o[T0 + stage].y = Pn.y;
609 r.o[T0 + stage].z = Pn.z;
610 r.o[T0 + stage].w = Pn.w;
John Bauman89401822014-05-06 15:04:28 -0400611 }
612 break;
613 case Context::TEXGEN_REFLECTION:
614 {
John Bauman19bac1e2014-05-06 15:23:49 -0400615 Vector4f R; // Reflection vector
John Bauman89401822014-05-06 15:04:28 -0400616
617 if(state.vertexNormalActive)
618 {
John Bauman19bac1e2014-05-06 15:23:49 -0400619 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400620
621 Nc = normal;
622
623 if(state.localViewerActive)
624 {
John Bauman19bac1e2014-05-06 15:23:49 -0400625 Vector4f Ec; // Eye vector in camera space
626 Vector4f N2;
John Bauman89401822014-05-06 15:04:28 -0400627
628 Ec = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
629 Ec = normalize(Ec);
630
631 // R = E - 2 * N * (E . N)
John Bauman19bac1e2014-05-06 15:23:49 -0400632 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
John Bauman89401822014-05-06 15:04:28 -0400633
634 R.x = Ec.x - Nc.x * dot;
635 R.y = Ec.y - Nc.y * dot;
636 R.z = Ec.z - Nc.z * dot;
637 }
638 else
639 {
640 // u = -2 * Nz * Nx
641 // v = -2 * Nz * Ny
642 // w = 1 - 2 * Nz * Nz
643
John Bauman19bac1e2014-05-06 15:23:49 -0400644 R.x = -Float4(2.0f) * Nc.z * Nc.x;
645 R.y = -Float4(2.0f) * Nc.z * Nc.y;
646 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
John Bauman89401822014-05-06 15:04:28 -0400647 }
648 }
649 else
650 {
John Bauman19bac1e2014-05-06 15:23:49 -0400651 R.x = Float4(0.0f);
652 R.y = Float4(0.0f);
653 R.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400654 }
655
John Bauman19bac1e2014-05-06 15:23:49 -0400656 R.w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400657
John Bauman19bac1e2014-05-06 15:23:49 -0400658 r.o[T0 + stage].x = R.x;
659 r.o[T0 + stage].y = R.y;
660 r.o[T0 + stage].z = R.z;
661 r.o[T0 + stage].w = R.w;
John Bauman89401822014-05-06 15:04:28 -0400662 }
663 break;
664 case Context::TEXGEN_SPHEREMAP:
665 {
John Bauman19bac1e2014-05-06 15:23:49 -0400666 Vector4f R; // Reflection vector
John Bauman89401822014-05-06 15:04:28 -0400667
668 if(state.vertexNormalActive)
669 {
John Bauman19bac1e2014-05-06 15:23:49 -0400670 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400671
672 Nc = normal;
673
674 if(state.localViewerActive)
675 {
John Bauman19bac1e2014-05-06 15:23:49 -0400676 Vector4f Ec; // Eye vector in camera space
677 Vector4f N2;
John Bauman89401822014-05-06 15:04:28 -0400678
679 Ec = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
680 Ec = normalize(Ec);
681
682 // R = E - 2 * N * (E . N)
John Bauman19bac1e2014-05-06 15:23:49 -0400683 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
John Bauman89401822014-05-06 15:04:28 -0400684
685 R.x = Ec.x - Nc.x * dot;
686 R.y = Ec.y - Nc.y * dot;
687 R.z = Ec.z - Nc.z * dot;
688 }
689 else
690 {
691 // u = -2 * Nz * Nx
692 // v = -2 * Nz * Ny
693 // w = 1 - 2 * Nz * Nz
694
John Bauman19bac1e2014-05-06 15:23:49 -0400695 R.x = -Float4(2.0f) * Nc.z * Nc.x;
696 R.y = -Float4(2.0f) * Nc.z * Nc.y;
697 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
John Bauman89401822014-05-06 15:04:28 -0400698 }
699 }
700 else
701 {
John Bauman19bac1e2014-05-06 15:23:49 -0400702 R.x = Float4(0.0f);
703 R.y = Float4(0.0f);
704 R.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400705 }
706
John Bauman19bac1e2014-05-06 15:23:49 -0400707 R.z -= Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400708 R = normalize(R);
John Bauman19bac1e2014-05-06 15:23:49 -0400709 R.x = Float4(0.5f) * R.x + Float4(0.5f);
710 R.y = Float4(0.5f) * R.y + Float4(0.5f);
John Bauman89401822014-05-06 15:04:28 -0400711
John Bauman19bac1e2014-05-06 15:23:49 -0400712 R.z = Float4(1.0f);
713 R.w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400714
John Bauman19bac1e2014-05-06 15:23:49 -0400715 r.o[T0 + stage].x = R.x;
716 r.o[T0 + stage].y = R.y;
717 r.o[T0 + stage].z = R.z;
718 r.o[T0 + stage].w = R.w;
John Bauman89401822014-05-06 15:04:28 -0400719 }
720 break;
721 default:
722 ASSERT(false);
723 }
724
John Bauman19bac1e2014-05-06 15:23:49 -0400725 Vector4f texTrans0;
726 Vector4f texTrans1;
727 Vector4f texTrans2;
728 Vector4f texTrans3;
John Bauman89401822014-05-06 15:04:28 -0400729
John Bauman19bac1e2014-05-06 15:23:49 -0400730 Vector4f T;
731 Vector4f t;
John Bauman89401822014-05-06 15:04:28 -0400732
John Bauman19bac1e2014-05-06 15:23:49 -0400733 T.x = r.o[T0 + stage].x;
734 T.y = r.o[T0 + stage].y;
735 T.z = r.o[T0 + stage].z;
736 T.w = r.o[T0 + stage].w;
John Bauman89401822014-05-06 15:04:28 -0400737
738 switch(state.textureState[stage].textureTransformCountActive)
739 {
740 case 4:
741 texTrans3.x = texTrans3.y = texTrans3.z = texTrans3.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][3])); // FIXME: Unpack
742 texTrans3.x = texTrans3.x.xxxx;
743 texTrans3.y = texTrans3.y.yyyy;
744 texTrans3.z = texTrans3.z.zzzz;
745 texTrans3.w = texTrans3.w.wwww;
746 t.w = dot4(T, texTrans3);
747 case 3:
748 texTrans2.x = texTrans2.y = texTrans2.z = texTrans2.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][2])); // FIXME: Unpack
749 texTrans2.x = texTrans2.x.xxxx;
750 texTrans2.y = texTrans2.y.yyyy;
751 texTrans2.z = texTrans2.z.zzzz;
752 texTrans2.w = texTrans2.w.wwww;
753 t.z = dot4(T, texTrans2);
754 case 2:
755 texTrans1.x = texTrans1.y = texTrans1.z = texTrans1.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][1])); // FIXME: Unpack
756 texTrans1.x = texTrans1.x.xxxx;
757 texTrans1.y = texTrans1.y.yyyy;
758 texTrans1.z = texTrans1.z.zzzz;
759 texTrans1.w = texTrans1.w.wwww;
760 t.y = dot4(T, texTrans1);
761 case 1:
762 texTrans0.x = texTrans0.y = texTrans0.z = texTrans0.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][0])); // FIXME: Unpack
763 texTrans0.x = texTrans0.x.xxxx;
764 texTrans0.y = texTrans0.y.yyyy;
765 texTrans0.z = texTrans0.z.zzzz;
766 texTrans0.w = texTrans0.w.wwww;
767 t.x = dot4(T, texTrans0);
768
John Bauman19bac1e2014-05-06 15:23:49 -0400769 r.o[T0 + stage].x = t.x;
770 r.o[T0 + stage].y = t.y;
771 r.o[T0 + stage].z = t.z;
772 r.o[T0 + stage].w = t.w;
John Bauman89401822014-05-06 15:04:28 -0400773 case 0:
774 break;
775 default:
776 ASSERT(false);
777 }
778 }
779 }
780
781 void VertexPipeline::processPointSize(Registers &r)
782 {
783 if(!state.pointSizeActive)
784 {
785 return; // Use global pointsize
786 }
787
788 if(state.input[PSize])
789 {
John Bauman19bac1e2014-05-06 15:23:49 -0400790 r.o[Pts].y = r.v[PSize].x;
John Bauman89401822014-05-06 15:04:28 -0400791 }
792 else
793 {
John Bauman19bac1e2014-05-06 15:23:49 -0400794 r.o[Pts].y = *Pointer<Float4>(r.data + OFFSET(DrawData,point.pointSize));
John Bauman89401822014-05-06 15:04:28 -0400795 }
796
797 if(state.pointScaleActive && !state.preTransformed)
798 {
John Bauman19bac1e2014-05-06 15:23:49 -0400799 Vector4f p = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
John Bauman89401822014-05-06 15:04:28 -0400800
801 Float4 d = Sqrt(dot3(p, p)); // FIXME: length(p);
802
803 Float4 A = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleA)); // FIXME: Unpack
804 Float4 B = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleB)); // FIXME: Unpack
805 Float4 C = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleC)); // FIXME: Unpack
806
807 A = RcpSqrt_pp(A + d * (B + d * C));
808
John Bauman19bac1e2014-05-06 15:23:49 -0400809 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 -0400810 }
811 }
812
John Bauman19bac1e2014-05-06 15:23:49 -0400813 Vector4f VertexPipeline::transform(Register &src, Pointer<Byte> &matrix, bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -0400814 {
John Bauman19bac1e2014-05-06 15:23:49 -0400815 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400816
817 if(homogeneous)
818 {
819 Float4 m[4][4];
820
821 for(int j = 0; j < 4; j++)
822 {
823 for(int i = 0; i < 4; i++)
824 {
825 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
826 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
827 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
828 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
829 }
830 }
831
832 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + m[0][3];
833 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + m[1][3];
834 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + m[2][3];
835 dst.w = src.x * m[3][0] + src.y * m[3][1] + src.z * m[3][2] + m[3][3];
836 }
837 else
838 {
839 Float4 m[3][3];
840
841 for(int j = 0; j < 3; j++)
842 {
843 for(int i = 0; i < 3; i++)
844 {
845 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
846 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
847 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
848 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
849 }
850 }
851
852 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
853 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
854 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
855 }
856
857 return dst;
858 }
859
John Bauman19bac1e2014-05-06 15:23:49 -0400860 Vector4f VertexPipeline::transform(Register &src, Pointer<Byte> &matrix, UInt index[4], bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -0400861 {
John Bauman19bac1e2014-05-06 15:23:49 -0400862 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400863
864 if(homogeneous)
865 {
866 Float4 m[4][4];
867
868 for(int j = 0; j < 4; j++)
869 {
870 for(int i = 0; i < 4; i++)
871 {
872 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
873 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
874 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
875 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
876 }
877 }
878
879 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + m[0][3];
880 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + m[1][3];
881 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + m[2][3];
882 dst.w = src.x * m[3][0] + src.y * m[3][1] + src.z * m[3][2] + m[3][3];
883 }
884 else
885 {
886 Float4 m[3][3];
887
888 for(int j = 0; j < 3; j++)
889 {
890 for(int i = 0; i < 3; i++)
891 {
892 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
893 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
894 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
895 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
896 }
897 }
898
899 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
900 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
901 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
902 }
903
904 return dst;
905 }
906
John Bauman19bac1e2014-05-06 15:23:49 -0400907 Vector4f VertexPipeline::normalize(Vector4f &src)
John Bauman89401822014-05-06 15:04:28 -0400908 {
John Bauman19bac1e2014-05-06 15:23:49 -0400909 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400910
911 Float4 rcpLength = RcpSqrt_pp(dot3(src, src));
912
913 dst.x = src.x * rcpLength;
914 dst.y = src.y * rcpLength;
915 dst.z = src.z * rcpLength;
916
917 return dst;
918 }
919
920 Float4 VertexPipeline::power(Float4 &src0, Float4 &src1)
921 {
922 Float4 dst = src0;
923
924 dst = dst * dst;
925 dst = dst * dst;
John Bauman19bac1e2014-05-06 15:23:49 -0400926 dst = Float4(As<Int4>(dst) - As<Int4>(Float4(1.0f)));
John Bauman89401822014-05-06 15:04:28 -0400927
928 dst *= src1;
929
John Bauman19bac1e2014-05-06 15:23:49 -0400930 dst = As<Float4>(Int4(dst) + As<Int4>(Float4(1.0f)));
John Bauman89401822014-05-06 15:04:28 -0400931 dst = RcpSqrt_pp(dst);
932 dst = RcpSqrt_pp(dst);
933
934 return dst;
935 }
936}