blob: c1e19daee5cfcb12f3d9ea5b1df76f28eba6a889 [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 "VertexProcessor.hpp"
13
John Bauman89401822014-05-06 15:04:28 -040014#include "Math.hpp"
15#include "VertexPipeline.hpp"
16#include "VertexProgram.hpp"
17#include "VertexShader.hpp"
18#include "PixelShader.hpp"
19#include "Constants.hpp"
20#include "Debug.hpp"
21
John Bauman66b8ab22014-05-06 15:57:45 -040022#include <string.h>
John Bauman89401822014-05-06 15:04:28 -040023
24namespace sw
25{
John Bauman66b8ab22014-05-06 15:57:45 -040026 bool precacheVertex = false;
27
John Bauman89401822014-05-06 15:04:28 -040028 void VertexCache::clear()
29 {
30 for(int i = 0; i < 16; i++)
31 {
32 tag[i] = 0x80000000;
33 }
34 }
35
36 unsigned int VertexProcessor::States::computeHash()
37 {
38 unsigned int *state = (unsigned int*)this;
39 unsigned int hash = 0;
40
Nicolas Capens5d961882016-01-01 23:18:14 -050041 for(unsigned int i = 0; i < sizeof(States) / 4; i++)
John Bauman89401822014-05-06 15:04:28 -040042 {
43 hash ^= state[i];
44 }
45
46 return hash;
47 }
48
49 VertexProcessor::State::State()
50 {
51 memset(this, 0, sizeof(State));
52 }
53
54 bool VertexProcessor::State::operator==(const State &state) const
55 {
56 if(hash != state.hash)
57 {
58 return false;
59 }
60
61 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
62 }
63
64 VertexProcessor::VertexProcessor(Context *context) : context(context)
65 {
66 for(int i = 0; i < 12; i++)
67 {
68 M[i] = 1;
69 }
70
71 V = 1;
72 B = 1;
73 P = 0;
74 PB = 0;
75 PBV = 0;
Nicolas Capens2ca19032016-01-15 16:54:13 -050076
John Bauman89401822014-05-06 15:04:28 -040077 for(int i = 0; i < 12; i++)
78 {
79 PBVM[i] = 0;
80 }
81
82 setLightingEnable(true);
83 setSpecularEnable(false);
84
85 for(int i = 0; i < 8; i++)
86 {
87 setLightEnable(i, false);
88 setLightPosition(i, 0);
89 }
90
91 updateMatrix = true;
92 updateViewMatrix = true;
93 updateBaseMatrix = true;
94 updateProjectionMatrix = true;
95 updateLighting = true;
96
97 for(int i = 0; i < 12; i++)
98 {
99 updateModelMatrix[i] = true;
100 }
101
102 routineCache = 0;
103 setRoutineCacheSize(1024);
104 }
105
106 VertexProcessor::~VertexProcessor()
107 {
108 delete routineCache;
109 routineCache = 0;
110 }
111
112 void VertexProcessor::setInputStream(int index, const Stream &stream)
113 {
114 context->input[index] = stream;
115 }
116
John Bauman89401822014-05-06 15:04:28 -0400117 void VertexProcessor::resetInputStreams(bool preTransformed)
118 {
Nicolas Capens0f250902015-06-25 15:25:29 -0400119 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400120 {
121 context->input[i].defaults();
122 }
123
124 context->preTransformed = preTransformed;
125 }
126
127 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
128 {
Alexis Hetu028f41b2016-01-13 14:40:47 -0500129 if(index < VERTEX_UNIFORM_VECTORS)
John Bauman89401822014-05-06 15:04:28 -0400130 {
131 c[index][0] = value[0];
132 c[index][1] = value[1];
133 c[index][2] = value[2];
134 c[index][3] = value[3];
135 }
136 else ASSERT(false);
137 }
138
139 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
140 {
141 if(index < 16)
142 {
143 i[index][0] = integer[0];
144 i[index][1] = integer[1];
145 i[index][2] = integer[2];
146 i[index][3] = integer[3];
147 }
148 else ASSERT(false);
149 }
150
151 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
152 {
153 if(index < 16)
154 {
155 b[index] = boolean != 0;
156 }
157 else ASSERT(false);
158 }
159
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400160 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
161 {
162 uniformBuffer[index] = buffer;
163 uniformBufferOffset[index] = offset;
164 }
165
166 void VertexProcessor::lockUniformBuffers(byte** u)
167 {
168 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
169 {
170 u[i] = uniformBuffer[i] ? static_cast<byte*>(uniformBuffer[i]->lock(PUBLIC, PRIVATE)) + uniformBufferOffset[i] : nullptr;
171 }
172 }
173
174 void VertexProcessor::unlockUniformBuffers()
175 {
176 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
177 {
178 if(uniformBuffer[i])
179 {
180 uniformBuffer[i]->unlock();
181 uniformBuffer[i] = nullptr;
182 }
183 }
184 }
185
John Bauman89401822014-05-06 15:04:28 -0400186 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
187 {
188 if(i < 12)
189 {
190 this->M[i] = M;
191
192 updateMatrix = true;
193 updateModelMatrix[i] = true;
194 updateLighting = true;
195 }
196 else ASSERT(false);
197 }
198
199 void VertexProcessor::setViewMatrix(const Matrix &V)
200 {
201 this->V = V;
202
203 updateMatrix = true;
204 updateViewMatrix = true;
205 }
206
207 void VertexProcessor::setBaseMatrix(const Matrix &B)
208 {
209 this->B = B;
210
211 updateMatrix = true;
212 updateBaseMatrix = true;
213 }
214
215 void VertexProcessor::setProjectionMatrix(const Matrix &P)
216 {
217 this->P = P;
218 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
219
220 updateMatrix = true;
221 updateProjectionMatrix = true;
222 }
223
224 void VertexProcessor::setLightingEnable(bool lightingEnable)
225 {
226 context->setLightingEnable(lightingEnable);
227
228 updateLighting = true;
229 }
230
231 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
232 {
233 if(light < 8)
234 {
235 context->setLightEnable(light, lightEnable);
236 }
237 else ASSERT(false);
238
239 updateLighting = true;
240 }
241
242 void VertexProcessor::setSpecularEnable(bool specularEnable)
243 {
244 context->setSpecularEnable(specularEnable);
245
246 updateLighting = true;
247 }
248
249 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
250 {
251 if(light < 8)
252 {
253 context->setLightPosition(light, lightPosition);
254 }
255 else ASSERT(false);
256
257 updateLighting = true;
258 }
259
260 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
261 {
262 if(light < 8)
263 {
264 ff.lightDiffuse[light][0] = lightDiffuse.r;
265 ff.lightDiffuse[light][1] = lightDiffuse.g;
266 ff.lightDiffuse[light][2] = lightDiffuse.b;
267 ff.lightDiffuse[light][3] = lightDiffuse.a;
268 }
269 else ASSERT(false);
270 }
271
272 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
273 {
274 if(light < 8)
275 {
276 ff.lightSpecular[light][0] = lightSpecular.r;
277 ff.lightSpecular[light][1] = lightSpecular.g;
278 ff.lightSpecular[light][2] = lightSpecular.b;
279 ff.lightSpecular[light][3] = lightSpecular.a;
280 }
281 else ASSERT(false);
282 }
283
284 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
285 {
286 if(light < 8)
287 {
288 ff.lightAmbient[light][0] = lightAmbient.r;
289 ff.lightAmbient[light][1] = lightAmbient.g;
290 ff.lightAmbient[light][2] = lightAmbient.b;
291 ff.lightAmbient[light][3] = lightAmbient.a;
292 }
293 else ASSERT(false);
294 }
295
296 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
297 {
298 if(light < 8)
299 {
Nicolas Capens2ca19032016-01-15 16:54:13 -0500300 ff.attenuationConstant[light] = replicate(constant);
John Bauman89401822014-05-06 15:04:28 -0400301 ff.attenuationLinear[light] = replicate(linear);
302 ff.attenuationQuadratic[light] = replicate(quadratic);
303 }
304 else ASSERT(false);
305 }
306
307 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
308 {
309 if(light < 8)
310 {
311 ff.lightRange[light] = lightRange;
312 }
313 else ASSERT(false);
314 }
315
316 void VertexProcessor::setFogEnable(bool fogEnable)
317 {
318 context->fogEnable = fogEnable;
319 }
320
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400321 void VertexProcessor::setVertexFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400322 {
323 context->vertexFogMode = fogMode;
324 }
325
Alexis Hetu6743bbf2015-04-21 17:06:14 -0400326 void VertexProcessor::setInstanceID(int instanceID)
327 {
328 context->instanceID = instanceID;
329 }
330
John Bauman89401822014-05-06 15:04:28 -0400331 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
332 {
333 context->setColorVertexEnable(colorVertexEnable);
334 }
335
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400336 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400337 {
338 context->setDiffuseMaterialSource(diffuseMaterialSource);
339 }
340
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400341 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400342 {
343 context->setSpecularMaterialSource(specularMaterialSource);
344 }
345
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400346 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400347 {
348 context->setAmbientMaterialSource(ambientMaterialSource);
349 }
350
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400351 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400352 {
353 context->setEmissiveMaterialSource(emissiveMaterialSource);
354 }
355
356 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
357 {
358 ff.globalAmbient[0] = globalAmbient.r;
359 ff.globalAmbient[1] = globalAmbient.g;
360 ff.globalAmbient[2] = globalAmbient.b;
361 ff.globalAmbient[3] = globalAmbient.a;
362 }
363
364 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
365 {
366 ff.materialEmission[0] = emission.r;
367 ff.materialEmission[1] = emission.g;
368 ff.materialEmission[2] = emission.b;
369 ff.materialEmission[3] = emission.a;
370 }
371
372 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
373 {
374 ff.materialAmbient[0] = materialAmbient.r;
375 ff.materialAmbient[1] = materialAmbient.g;
376 ff.materialAmbient[2] = materialAmbient.b;
377 ff.materialAmbient[3] = materialAmbient.a;
378 }
379
380 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
381 {
382 ff.materialDiffuse[0] = diffuseColor.r;
383 ff.materialDiffuse[1] = diffuseColor.g;
384 ff.materialDiffuse[2] = diffuseColor.b;
385 ff.materialDiffuse[3] = diffuseColor.a;
386 }
387
388 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
389 {
390 ff.materialSpecular[0] = specularColor.r;
391 ff.materialSpecular[1] = specularColor.g;
392 ff.materialSpecular[2] = specularColor.b;
393 ff.materialSpecular[3] = specularColor.a;
394 }
395
396 void VertexProcessor::setMaterialShininess(float specularPower)
397 {
398 ff.materialShininess = specularPower;
399 }
400
401 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
402 {
403 if(light < 8)
404 {
405 ff.lightPosition[light][0] = P.x;
406 ff.lightPosition[light][1] = P.y;
407 ff.lightPosition[light][2] = P.z;
408 ff.lightPosition[light][3] = 1;
409 }
410 else ASSERT(false);
411 }
412
413 void VertexProcessor::setRangeFogEnable(bool enable)
414 {
415 context->rangeFogEnable = enable;
416 }
417
418 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
419 {
420 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
421 }
422
423 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
424 {
425 if(vertexBlendMatrixCount <= 4)
426 {
427 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
428 }
429 else ASSERT(false);
430 }
431
432 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
433 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400434 if(stage < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400435 {
436 context->textureWrap[stage] = mask;
437 }
438 else ASSERT(false);
439
440 context->textureWrapActive = false;
441
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400442 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400443 {
444 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
445 }
446 }
447
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400448 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400449 {
450 if(stage < 8)
451 {
452 context->texGen[stage] = texGen;
453 }
454 else ASSERT(false);
455 }
456
457 void VertexProcessor::setLocalViewer(bool localViewer)
458 {
459 context->localViewer = localViewer;
460 }
461
462 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
463 {
464 context->normalizeNormals = normalizeNormals;
465 }
466
467 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
468 {
469 for(int i = 0; i < 4; i++)
470 {
471 for(int j = 0; j < 4; j++)
472 {
473 ff.textureTransform[stage][i][j] = T[i][j];
474 }
475 }
476 }
477
478 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
479 {
480 context->textureTransformCount[stage] = count;
481 context->textureTransformProject[stage] = project;
482 }
483
484 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
485 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400486 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400487 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400488 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
John Bauman89401822014-05-06 15:04:28 -0400489 }
490 else ASSERT(false);
491 }
492
493 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
494 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400495 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400496 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400497 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
John Bauman89401822014-05-06 15:04:28 -0400498 }
499 else ASSERT(false);
500 }
501
502 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
503 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400504 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400505 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400506 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
John Bauman89401822014-05-06 15:04:28 -0400507 }
508 else ASSERT(false);
509 }
510
511 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
512 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400513 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400514 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400515 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400516 }
517 else ASSERT(false);
518 }
519
520 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
521 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400522 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400523 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400524 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400525 }
526 else ASSERT(false);
527 }
528
529 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
530 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400531 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400532 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400533 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400534 }
535 else ASSERT(false);
536 }
537
538 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
539 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400540 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400541 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400542 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
John Bauman89401822014-05-06 15:04:28 -0400543 }
544 else ASSERT(false);
545 }
546
547 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
548 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400549 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400550 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400551 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
John Bauman89401822014-05-06 15:04:28 -0400552 }
553 else ASSERT(false);
554 }
555
556 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
557 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400558 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400559 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400560 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
John Bauman89401822014-05-06 15:04:28 -0400561 }
562 else ASSERT(false);
563 }
564
Alexis Hetu617a5d52014-11-13 10:56:20 -0500565 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400566 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400567 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400568 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400569 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
John Bauman89401822014-05-06 15:04:28 -0400570 }
571 else ASSERT(false);
572 }
573
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400574 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
575 {
576 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
577 {
578 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
579 }
580 else ASSERT(false);
581 }
582
583 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
584 {
585 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
586 {
587 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
588 }
589 else ASSERT(false);
590 }
591
592 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
593 {
594 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
595 {
596 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
597 }
598 else ASSERT(false);
599 }
600
601 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
602 {
603 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
604 {
605 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
606 }
607 else ASSERT(false);
608 }
609
John Bauman89401822014-05-06 15:04:28 -0400610 void VertexProcessor::setPointSize(float pointSize)
611 {
612 point.pointSize = replicate(pointSize);
613 }
614
615 void VertexProcessor::setPointSizeMin(float pointSizeMin)
616 {
617 point.pointSizeMin = pointSizeMin;
618 }
619
620 void VertexProcessor::setPointSizeMax(float pointSizeMax)
621 {
622 point.pointSizeMax = pointSizeMax;
623 }
624
625 void VertexProcessor::setPointScaleA(float pointScaleA)
626 {
627 point.pointScaleA = pointScaleA;
628 }
629
630 void VertexProcessor::setPointScaleB(float pointScaleB)
631 {
632 point.pointScaleB = pointScaleB;
633 }
634
635 void VertexProcessor::setPointScaleC(float pointScaleC)
636 {
637 point.pointScaleC = pointScaleC;
638 }
639
640 const Matrix &VertexProcessor::getModelTransform(int i)
641 {
642 updateTransform();
643 return PBVM[i];
644 }
645
646 const Matrix &VertexProcessor::getViewTransform()
647 {
648 updateTransform();
649 return PBV;
650 }
651
652 bool VertexProcessor::isFixedFunction()
653 {
654 return !context->vertexShader;
655 }
656
657 void VertexProcessor::setTransform(const Matrix &M, int i)
658 {
659 ff.transformT[i][0][0] = M[0][0];
660 ff.transformT[i][0][1] = M[1][0];
661 ff.transformT[i][0][2] = M[2][0];
662 ff.transformT[i][0][3] = M[3][0];
663
664 ff.transformT[i][1][0] = M[0][1];
665 ff.transformT[i][1][1] = M[1][1];
666 ff.transformT[i][1][2] = M[2][1];
667 ff.transformT[i][1][3] = M[3][1];
668
669 ff.transformT[i][2][0] = M[0][2];
670 ff.transformT[i][2][1] = M[1][2];
671 ff.transformT[i][2][2] = M[2][2];
672 ff.transformT[i][2][3] = M[3][2];
673
674 ff.transformT[i][3][0] = M[0][3];
675 ff.transformT[i][3][1] = M[1][3];
676 ff.transformT[i][3][2] = M[2][3];
677 ff.transformT[i][3][3] = M[3][3];
678 }
679
680 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
681 {
682 ff.cameraTransformT[i][0][0] = M[0][0];
683 ff.cameraTransformT[i][0][1] = M[1][0];
684 ff.cameraTransformT[i][0][2] = M[2][0];
685 ff.cameraTransformT[i][0][3] = M[3][0];
686
687 ff.cameraTransformT[i][1][0] = M[0][1];
688 ff.cameraTransformT[i][1][1] = M[1][1];
689 ff.cameraTransformT[i][1][2] = M[2][1];
690 ff.cameraTransformT[i][1][3] = M[3][1];
691
692 ff.cameraTransformT[i][2][0] = M[0][2];
693 ff.cameraTransformT[i][2][1] = M[1][2];
694 ff.cameraTransformT[i][2][2] = M[2][2];
695 ff.cameraTransformT[i][2][3] = M[3][2];
696
697 ff.cameraTransformT[i][3][0] = M[0][3];
698 ff.cameraTransformT[i][3][1] = M[1][3];
699 ff.cameraTransformT[i][3][2] = M[2][3];
700 ff.cameraTransformT[i][3][3] = M[3][3];
701 }
702
703 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
704 {
705 ff.normalTransformT[i][0][0] = M[0][0];
706 ff.normalTransformT[i][0][1] = M[1][0];
707 ff.normalTransformT[i][0][2] = M[2][0];
708 ff.normalTransformT[i][0][3] = M[3][0];
709
710 ff.normalTransformT[i][1][0] = M[0][1];
711 ff.normalTransformT[i][1][1] = M[1][1];
712 ff.normalTransformT[i][1][2] = M[2][1];
713 ff.normalTransformT[i][1][3] = M[3][1];
714
715 ff.normalTransformT[i][2][0] = M[0][2];
716 ff.normalTransformT[i][2][1] = M[1][2];
717 ff.normalTransformT[i][2][2] = M[2][2];
718 ff.normalTransformT[i][2][3] = M[3][2];
719
720 ff.normalTransformT[i][3][0] = M[0][3];
721 ff.normalTransformT[i][3][1] = M[1][3];
722 ff.normalTransformT[i][3][2] = M[2][3];
723 ff.normalTransformT[i][3][3] = M[3][3];
724 }
725
726 void VertexProcessor::updateTransform()
727 {
728 if(!updateMatrix) return;
729
730 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
731
732 if(updateProjectionMatrix)
733 {
734 PB = P * B;
735 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500736
John Bauman89401822014-05-06 15:04:28 -0400737 for(int i = 0; i < activeMatrices; i++)
738 {
739 PBVM[i] = PBV * M[i];
740 updateModelMatrix[i] = false;
741 }
742
743 updateProjectionMatrix = false;
744 updateBaseMatrix = false;
745 updateViewMatrix = false;
746 }
747
748 if(updateBaseMatrix)
749 {
750 PB = P * B;
751 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500752
John Bauman89401822014-05-06 15:04:28 -0400753 for(int i = 0; i < activeMatrices; i++)
754 {
755 PBVM[i] = PBV * M[i];
756 updateModelMatrix[i] = false;
757 }
758
759 updateBaseMatrix = false;
760 updateViewMatrix = false;
761 }
762
763 if(updateViewMatrix)
764 {
765 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500766
John Bauman89401822014-05-06 15:04:28 -0400767 for(int i = 0; i < activeMatrices; i++)
768 {
769 PBVM[i] = PBV * M[i];
770 updateModelMatrix[i] = false;
771 }
772
773 updateViewMatrix = false;
774 }
775
776 for(int i = 0; i < activeMatrices; i++)
777 {
778 if(updateModelMatrix[i])
779 {
780 PBVM[i] = PBV * M[i];
781 updateModelMatrix[i] = false;
782 }
783 }
784
785 for(int i = 0; i < activeMatrices; i++)
786 {
787 setTransform(PBVM[i], i);
788 setCameraTransform(B * V * M[i], i);
789 setNormalTransform(~!(B * V * M[i]), i);
790 }
791
792 updateMatrix = false;
793 }
794
795 void VertexProcessor::setRoutineCacheSize(int cacheSize)
796 {
797 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400798 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400799 }
800
801 const VertexProcessor::State VertexProcessor::update()
802 {
803 if(isFixedFunction())
804 {
805 updateTransform();
806
807 if(updateLighting)
808 {
809 for(int i = 0; i < 8; i++)
810 {
811 if(context->vertexLightActive(i))
812 {
813 // Light position in camera coordinates
814 setLightViewPosition(i, B * V * context->getLightPosition(i));
815 }
816 }
817
818 updateLighting = false;
819 }
820 }
821
822 State state;
823
824 if(context->vertexShader)
825 {
John Bauman19bac1e2014-05-06 15:23:49 -0400826 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400827 }
828 else
829 {
John Bauman19bac1e2014-05-06 15:23:49 -0400830 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400831 }
832
833 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500834 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
John Bauman89401822014-05-06 15:04:28 -0400835 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
836 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500837
John Bauman89401822014-05-06 15:04:28 -0400838 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
839 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
840 state.vertexNormalActive = context->vertexNormalActive();
841 state.normalizeNormals = context->normalizeNormalsActive();
842 state.vertexLightingActive = context->vertexLightingActive();
843 state.diffuseActive = context->diffuseActive();
844 state.specularActive = context->specularActive();
845 state.vertexSpecularActive = context->vertexSpecularActive();
846
847 state.vertexLightActive = context->vertexLightActive(0) << 0 |
848 context->vertexLightActive(1) << 1 |
849 context->vertexLightActive(2) << 2 |
850 context->vertexLightActive(3) << 3 |
851 context->vertexLightActive(4) << 4 |
852 context->vertexLightActive(5) << 5 |
853 context->vertexLightActive(6) << 6 |
854 context->vertexLightActive(7) << 7;
855
856 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
857 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
858 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
859 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
860 state.fogActive = context->fogActive();
861 state.vertexFogMode = context->vertexFogModeActive();
862 state.rangeFogActive = context->rangeFogActive();
863 state.localViewerActive = context->localViewerActive();
864 state.pointSizeActive = context->pointSizeActive();
865 state.pointScaleActive = context->pointScaleActive();
866
867 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400868 state.superSampling = context->getSuperSampleCount() > 1;
869 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400870
Nicolas Capens0f250902015-06-25 15:25:29 -0400871 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400872 {
873 state.input[i].type = context->input[i].type;
874 state.input[i].count = context->input[i].count;
875 state.input[i].normalized = context->input[i].normalized;
876 }
877
878 if(!context->vertexShader)
879 {
880 for(int i = 0; i < 8; i++)
881 {
882 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
883 state.textureState[i].texGenActive = context->texGenActive(i);
884 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
885 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
886 }
887 }
888 else
889 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400890 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400891 {
892 if(context->vertexShader->usesSampler(i))
893 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400894 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400895 }
896 }
897 }
898
899 if(context->vertexShader) // FIXME: Also when pre-transformed?
900 {
901 for(int i = 0; i < 12; i++)
902 {
903 state.output[i].xWrite = context->vertexShader->output[i][0].active();
904 state.output[i].yWrite = context->vertexShader->output[i][1].active();
905 state.output[i].zWrite = context->vertexShader->output[i][2].active();
906 state.output[i].wWrite = context->vertexShader->output[i][3].active();
907 }
908 }
909 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
910 {
911 state.output[Pos].write = 0xF;
912
913 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
914 {
915 state.output[D0].write = 0xF;
916 }
Nicolas Capens2ca19032016-01-15 16:54:13 -0500917
John Bauman89401822014-05-06 15:04:28 -0400918 if(context->specularActive())
919 {
920 state.output[D1].write = 0xF;
921 }
922
923 for(int stage = 0; stage < 8; stage++)
924 {
John Bauman19bac1e2014-05-06 15:23:49 -0400925 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
926 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
927 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
928 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400929 }
930
931 if(context->fogActive())
932 {
933 state.output[Fog].xWrite = true;
934 }
935
936 if(context->pointSizeActive())
937 {
938 state.output[Pts].yWrite = true;
939 }
940 }
941 else
942 {
943 state.output[Pos].write = 0xF;
944
945 for(int i = 0; i < 2; i++)
946 {
947 if(context->input[Color0 + i])
948 {
949 state.output[D0 + i].write = 0xF;
950 }
951 }
952
953 for(int i = 0; i < 8; i++)
954 {
955 if(context->input[TexCoord0 + i])
956 {
957 state.output[T0 + i].write = 0xF;
958 }
959 }
960
John Bauman66b8ab22014-05-06 15:57:45 -0400961 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400962 {
963 state.output[Pts].yWrite = true;
964 }
965 }
966
967 if(context->vertexShaderVersion() < 0x0300)
968 {
969 state.output[D0].clamp = 0xF;
970 state.output[D1].clamp = 0xF;
971 state.output[Fog].xClamp = true;
972 }
973
974 state.hash = state.computeHash();
975
976 return state;
977 }
978
979 Routine *VertexProcessor::routine(const State &state)
980 {
981 Routine *routine = routineCache->query(state);
982
983 if(!routine) // Create one
984 {
985 VertexRoutine *generator = 0;
986
987 if(state.fixedFunction)
988 {
989 generator = new VertexPipeline(state);
990 }
991 else
992 {
993 generator = new VertexProgram(state, context->vertexShader);
994 }
995
996 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -0500997 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -0400998 delete generator;
999
1000 routineCache->add(state, routine);
1001 }
1002
1003 return routine;
1004 }
1005}