blob: b71fdb247a11e04adbf3fec363b894a97be93d06 [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);
Nicolas Capens3d7be4e2016-02-07 22:47:00 -0500104
105 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
106 {
107 uniformBuffer[i] = nullptr;
108 }
John Bauman89401822014-05-06 15:04:28 -0400109 }
110
111 VertexProcessor::~VertexProcessor()
112 {
113 delete routineCache;
114 routineCache = 0;
115 }
116
117 void VertexProcessor::setInputStream(int index, const Stream &stream)
118 {
119 context->input[index] = stream;
120 }
121
John Bauman89401822014-05-06 15:04:28 -0400122 void VertexProcessor::resetInputStreams(bool preTransformed)
123 {
Nicolas Capens0f250902015-06-25 15:25:29 -0400124 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400125 {
126 context->input[i].defaults();
127 }
128
129 context->preTransformed = preTransformed;
130 }
131
132 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
133 {
Alexis Hetu028f41b2016-01-13 14:40:47 -0500134 if(index < VERTEX_UNIFORM_VECTORS)
John Bauman89401822014-05-06 15:04:28 -0400135 {
136 c[index][0] = value[0];
137 c[index][1] = value[1];
138 c[index][2] = value[2];
139 c[index][3] = value[3];
140 }
141 else ASSERT(false);
142 }
143
144 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
145 {
146 if(index < 16)
147 {
148 i[index][0] = integer[0];
149 i[index][1] = integer[1];
150 i[index][2] = integer[2];
151 i[index][3] = integer[3];
152 }
153 else ASSERT(false);
154 }
155
156 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
157 {
158 if(index < 16)
159 {
160 b[index] = boolean != 0;
161 }
162 else ASSERT(false);
163 }
164
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400165 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
166 {
167 uniformBuffer[index] = buffer;
168 uniformBufferOffset[index] = offset;
169 }
170
171 void VertexProcessor::lockUniformBuffers(byte** u)
172 {
173 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
174 {
175 u[i] = uniformBuffer[i] ? static_cast<byte*>(uniformBuffer[i]->lock(PUBLIC, PRIVATE)) + uniformBufferOffset[i] : nullptr;
176 }
177 }
178
179 void VertexProcessor::unlockUniformBuffers()
180 {
181 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
182 {
183 if(uniformBuffer[i])
184 {
185 uniformBuffer[i]->unlock();
186 uniformBuffer[i] = nullptr;
187 }
188 }
189 }
190
John Bauman89401822014-05-06 15:04:28 -0400191 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
192 {
193 if(i < 12)
194 {
195 this->M[i] = M;
196
197 updateMatrix = true;
198 updateModelMatrix[i] = true;
199 updateLighting = true;
200 }
201 else ASSERT(false);
202 }
203
204 void VertexProcessor::setViewMatrix(const Matrix &V)
205 {
206 this->V = V;
207
208 updateMatrix = true;
209 updateViewMatrix = true;
210 }
211
212 void VertexProcessor::setBaseMatrix(const Matrix &B)
213 {
214 this->B = B;
215
216 updateMatrix = true;
217 updateBaseMatrix = true;
218 }
219
220 void VertexProcessor::setProjectionMatrix(const Matrix &P)
221 {
222 this->P = P;
223 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
224
225 updateMatrix = true;
226 updateProjectionMatrix = true;
227 }
228
229 void VertexProcessor::setLightingEnable(bool lightingEnable)
230 {
231 context->setLightingEnable(lightingEnable);
232
233 updateLighting = true;
234 }
235
236 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
237 {
238 if(light < 8)
239 {
240 context->setLightEnable(light, lightEnable);
241 }
242 else ASSERT(false);
243
244 updateLighting = true;
245 }
246
247 void VertexProcessor::setSpecularEnable(bool specularEnable)
248 {
249 context->setSpecularEnable(specularEnable);
250
251 updateLighting = true;
252 }
253
254 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
255 {
256 if(light < 8)
257 {
258 context->setLightPosition(light, lightPosition);
259 }
260 else ASSERT(false);
261
262 updateLighting = true;
263 }
264
265 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
266 {
267 if(light < 8)
268 {
269 ff.lightDiffuse[light][0] = lightDiffuse.r;
270 ff.lightDiffuse[light][1] = lightDiffuse.g;
271 ff.lightDiffuse[light][2] = lightDiffuse.b;
272 ff.lightDiffuse[light][3] = lightDiffuse.a;
273 }
274 else ASSERT(false);
275 }
276
277 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
278 {
279 if(light < 8)
280 {
281 ff.lightSpecular[light][0] = lightSpecular.r;
282 ff.lightSpecular[light][1] = lightSpecular.g;
283 ff.lightSpecular[light][2] = lightSpecular.b;
284 ff.lightSpecular[light][3] = lightSpecular.a;
285 }
286 else ASSERT(false);
287 }
288
289 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
290 {
291 if(light < 8)
292 {
293 ff.lightAmbient[light][0] = lightAmbient.r;
294 ff.lightAmbient[light][1] = lightAmbient.g;
295 ff.lightAmbient[light][2] = lightAmbient.b;
296 ff.lightAmbient[light][3] = lightAmbient.a;
297 }
298 else ASSERT(false);
299 }
300
301 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
302 {
303 if(light < 8)
304 {
Nicolas Capens2ca19032016-01-15 16:54:13 -0500305 ff.attenuationConstant[light] = replicate(constant);
John Bauman89401822014-05-06 15:04:28 -0400306 ff.attenuationLinear[light] = replicate(linear);
307 ff.attenuationQuadratic[light] = replicate(quadratic);
308 }
309 else ASSERT(false);
310 }
311
312 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
313 {
314 if(light < 8)
315 {
316 ff.lightRange[light] = lightRange;
317 }
318 else ASSERT(false);
319 }
320
321 void VertexProcessor::setFogEnable(bool fogEnable)
322 {
323 context->fogEnable = fogEnable;
324 }
325
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400326 void VertexProcessor::setVertexFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400327 {
328 context->vertexFogMode = fogMode;
329 }
330
Alexis Hetu6743bbf2015-04-21 17:06:14 -0400331 void VertexProcessor::setInstanceID(int instanceID)
332 {
333 context->instanceID = instanceID;
334 }
335
John Bauman89401822014-05-06 15:04:28 -0400336 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
337 {
338 context->setColorVertexEnable(colorVertexEnable);
339 }
340
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400341 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400342 {
343 context->setDiffuseMaterialSource(diffuseMaterialSource);
344 }
345
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400346 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400347 {
348 context->setSpecularMaterialSource(specularMaterialSource);
349 }
350
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400351 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400352 {
353 context->setAmbientMaterialSource(ambientMaterialSource);
354 }
355
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400356 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400357 {
358 context->setEmissiveMaterialSource(emissiveMaterialSource);
359 }
360
361 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
362 {
363 ff.globalAmbient[0] = globalAmbient.r;
364 ff.globalAmbient[1] = globalAmbient.g;
365 ff.globalAmbient[2] = globalAmbient.b;
366 ff.globalAmbient[3] = globalAmbient.a;
367 }
368
369 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
370 {
371 ff.materialEmission[0] = emission.r;
372 ff.materialEmission[1] = emission.g;
373 ff.materialEmission[2] = emission.b;
374 ff.materialEmission[3] = emission.a;
375 }
376
377 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
378 {
379 ff.materialAmbient[0] = materialAmbient.r;
380 ff.materialAmbient[1] = materialAmbient.g;
381 ff.materialAmbient[2] = materialAmbient.b;
382 ff.materialAmbient[3] = materialAmbient.a;
383 }
384
385 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
386 {
387 ff.materialDiffuse[0] = diffuseColor.r;
388 ff.materialDiffuse[1] = diffuseColor.g;
389 ff.materialDiffuse[2] = diffuseColor.b;
390 ff.materialDiffuse[3] = diffuseColor.a;
391 }
392
393 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
394 {
395 ff.materialSpecular[0] = specularColor.r;
396 ff.materialSpecular[1] = specularColor.g;
397 ff.materialSpecular[2] = specularColor.b;
398 ff.materialSpecular[3] = specularColor.a;
399 }
400
401 void VertexProcessor::setMaterialShininess(float specularPower)
402 {
403 ff.materialShininess = specularPower;
404 }
405
406 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
407 {
408 if(light < 8)
409 {
410 ff.lightPosition[light][0] = P.x;
411 ff.lightPosition[light][1] = P.y;
412 ff.lightPosition[light][2] = P.z;
413 ff.lightPosition[light][3] = 1;
414 }
415 else ASSERT(false);
416 }
417
418 void VertexProcessor::setRangeFogEnable(bool enable)
419 {
420 context->rangeFogEnable = enable;
421 }
422
423 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
424 {
425 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
426 }
427
428 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
429 {
430 if(vertexBlendMatrixCount <= 4)
431 {
432 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
433 }
434 else ASSERT(false);
435 }
436
437 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
438 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400439 if(stage < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400440 {
441 context->textureWrap[stage] = mask;
442 }
443 else ASSERT(false);
444
445 context->textureWrapActive = false;
446
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400447 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400448 {
449 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
450 }
451 }
452
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400453 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400454 {
455 if(stage < 8)
456 {
457 context->texGen[stage] = texGen;
458 }
459 else ASSERT(false);
460 }
461
462 void VertexProcessor::setLocalViewer(bool localViewer)
463 {
464 context->localViewer = localViewer;
465 }
466
467 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
468 {
469 context->normalizeNormals = normalizeNormals;
470 }
471
472 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
473 {
474 for(int i = 0; i < 4; i++)
475 {
476 for(int j = 0; j < 4; j++)
477 {
478 ff.textureTransform[stage][i][j] = T[i][j];
479 }
480 }
481 }
482
483 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
484 {
485 context->textureTransformCount[stage] = count;
486 context->textureTransformProject[stage] = project;
487 }
488
489 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
490 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400491 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400492 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400493 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
John Bauman89401822014-05-06 15:04:28 -0400494 }
495 else ASSERT(false);
496 }
497
498 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
499 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400500 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400501 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400502 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
John Bauman89401822014-05-06 15:04:28 -0400503 }
504 else ASSERT(false);
505 }
506
507 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
508 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400509 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400510 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400511 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
John Bauman89401822014-05-06 15:04:28 -0400512 }
513 else ASSERT(false);
514 }
515
516 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
517 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400518 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400519 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400520 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400521 }
522 else ASSERT(false);
523 }
524
525 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
526 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400527 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400528 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400529 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400530 }
531 else ASSERT(false);
532 }
533
534 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
535 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400536 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400537 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400538 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400539 }
540 else ASSERT(false);
541 }
542
543 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
544 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400545 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400546 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400547 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
John Bauman89401822014-05-06 15:04:28 -0400548 }
549 else ASSERT(false);
550 }
551
552 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
553 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400554 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400555 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400556 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
John Bauman89401822014-05-06 15:04:28 -0400557 }
558 else ASSERT(false);
559 }
560
561 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
562 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400563 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400564 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400565 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
John Bauman89401822014-05-06 15:04:28 -0400566 }
567 else ASSERT(false);
568 }
569
Alexis Hetu617a5d52014-11-13 10:56:20 -0500570 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400571 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400572 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400573 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400574 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
John Bauman89401822014-05-06 15:04:28 -0400575 }
576 else ASSERT(false);
577 }
578
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400579 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
580 {
581 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
582 {
583 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
584 }
585 else ASSERT(false);
586 }
587
588 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
589 {
590 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
591 {
592 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
593 }
594 else ASSERT(false);
595 }
596
597 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
598 {
599 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
600 {
601 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
602 }
603 else ASSERT(false);
604 }
605
606 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
607 {
608 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
609 {
610 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
611 }
612 else ASSERT(false);
613 }
614
John Bauman89401822014-05-06 15:04:28 -0400615 void VertexProcessor::setPointSize(float pointSize)
616 {
617 point.pointSize = replicate(pointSize);
618 }
619
620 void VertexProcessor::setPointSizeMin(float pointSizeMin)
621 {
622 point.pointSizeMin = pointSizeMin;
623 }
624
625 void VertexProcessor::setPointSizeMax(float pointSizeMax)
626 {
627 point.pointSizeMax = pointSizeMax;
628 }
629
630 void VertexProcessor::setPointScaleA(float pointScaleA)
631 {
632 point.pointScaleA = pointScaleA;
633 }
634
635 void VertexProcessor::setPointScaleB(float pointScaleB)
636 {
637 point.pointScaleB = pointScaleB;
638 }
639
640 void VertexProcessor::setPointScaleC(float pointScaleC)
641 {
642 point.pointScaleC = pointScaleC;
643 }
644
645 const Matrix &VertexProcessor::getModelTransform(int i)
646 {
647 updateTransform();
648 return PBVM[i];
649 }
650
651 const Matrix &VertexProcessor::getViewTransform()
652 {
653 updateTransform();
654 return PBV;
655 }
656
657 bool VertexProcessor::isFixedFunction()
658 {
659 return !context->vertexShader;
660 }
661
662 void VertexProcessor::setTransform(const Matrix &M, int i)
663 {
664 ff.transformT[i][0][0] = M[0][0];
665 ff.transformT[i][0][1] = M[1][0];
666 ff.transformT[i][0][2] = M[2][0];
667 ff.transformT[i][0][3] = M[3][0];
668
669 ff.transformT[i][1][0] = M[0][1];
670 ff.transformT[i][1][1] = M[1][1];
671 ff.transformT[i][1][2] = M[2][1];
672 ff.transformT[i][1][3] = M[3][1];
673
674 ff.transformT[i][2][0] = M[0][2];
675 ff.transformT[i][2][1] = M[1][2];
676 ff.transformT[i][2][2] = M[2][2];
677 ff.transformT[i][2][3] = M[3][2];
678
679 ff.transformT[i][3][0] = M[0][3];
680 ff.transformT[i][3][1] = M[1][3];
681 ff.transformT[i][3][2] = M[2][3];
682 ff.transformT[i][3][3] = M[3][3];
683 }
684
685 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
686 {
687 ff.cameraTransformT[i][0][0] = M[0][0];
688 ff.cameraTransformT[i][0][1] = M[1][0];
689 ff.cameraTransformT[i][0][2] = M[2][0];
690 ff.cameraTransformT[i][0][3] = M[3][0];
691
692 ff.cameraTransformT[i][1][0] = M[0][1];
693 ff.cameraTransformT[i][1][1] = M[1][1];
694 ff.cameraTransformT[i][1][2] = M[2][1];
695 ff.cameraTransformT[i][1][3] = M[3][1];
696
697 ff.cameraTransformT[i][2][0] = M[0][2];
698 ff.cameraTransformT[i][2][1] = M[1][2];
699 ff.cameraTransformT[i][2][2] = M[2][2];
700 ff.cameraTransformT[i][2][3] = M[3][2];
701
702 ff.cameraTransformT[i][3][0] = M[0][3];
703 ff.cameraTransformT[i][3][1] = M[1][3];
704 ff.cameraTransformT[i][3][2] = M[2][3];
705 ff.cameraTransformT[i][3][3] = M[3][3];
706 }
707
708 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
709 {
710 ff.normalTransformT[i][0][0] = M[0][0];
711 ff.normalTransformT[i][0][1] = M[1][0];
712 ff.normalTransformT[i][0][2] = M[2][0];
713 ff.normalTransformT[i][0][3] = M[3][0];
714
715 ff.normalTransformT[i][1][0] = M[0][1];
716 ff.normalTransformT[i][1][1] = M[1][1];
717 ff.normalTransformT[i][1][2] = M[2][1];
718 ff.normalTransformT[i][1][3] = M[3][1];
719
720 ff.normalTransformT[i][2][0] = M[0][2];
721 ff.normalTransformT[i][2][1] = M[1][2];
722 ff.normalTransformT[i][2][2] = M[2][2];
723 ff.normalTransformT[i][2][3] = M[3][2];
724
725 ff.normalTransformT[i][3][0] = M[0][3];
726 ff.normalTransformT[i][3][1] = M[1][3];
727 ff.normalTransformT[i][3][2] = M[2][3];
728 ff.normalTransformT[i][3][3] = M[3][3];
729 }
730
731 void VertexProcessor::updateTransform()
732 {
733 if(!updateMatrix) return;
734
735 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
736
737 if(updateProjectionMatrix)
738 {
739 PB = P * B;
740 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500741
John Bauman89401822014-05-06 15:04:28 -0400742 for(int i = 0; i < activeMatrices; i++)
743 {
744 PBVM[i] = PBV * M[i];
745 updateModelMatrix[i] = false;
746 }
747
748 updateProjectionMatrix = false;
749 updateBaseMatrix = false;
750 updateViewMatrix = false;
751 }
752
753 if(updateBaseMatrix)
754 {
755 PB = P * B;
756 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500757
John Bauman89401822014-05-06 15:04:28 -0400758 for(int i = 0; i < activeMatrices; i++)
759 {
760 PBVM[i] = PBV * M[i];
761 updateModelMatrix[i] = false;
762 }
763
764 updateBaseMatrix = false;
765 updateViewMatrix = false;
766 }
767
768 if(updateViewMatrix)
769 {
770 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500771
John Bauman89401822014-05-06 15:04:28 -0400772 for(int i = 0; i < activeMatrices; i++)
773 {
774 PBVM[i] = PBV * M[i];
775 updateModelMatrix[i] = false;
776 }
777
778 updateViewMatrix = false;
779 }
780
781 for(int i = 0; i < activeMatrices; i++)
782 {
783 if(updateModelMatrix[i])
784 {
785 PBVM[i] = PBV * M[i];
786 updateModelMatrix[i] = false;
787 }
788 }
789
790 for(int i = 0; i < activeMatrices; i++)
791 {
792 setTransform(PBVM[i], i);
793 setCameraTransform(B * V * M[i], i);
794 setNormalTransform(~!(B * V * M[i]), i);
795 }
796
797 updateMatrix = false;
798 }
799
800 void VertexProcessor::setRoutineCacheSize(int cacheSize)
801 {
802 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400803 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400804 }
805
806 const VertexProcessor::State VertexProcessor::update()
807 {
808 if(isFixedFunction())
809 {
810 updateTransform();
811
812 if(updateLighting)
813 {
814 for(int i = 0; i < 8; i++)
815 {
816 if(context->vertexLightActive(i))
817 {
818 // Light position in camera coordinates
819 setLightViewPosition(i, B * V * context->getLightPosition(i));
820 }
821 }
822
823 updateLighting = false;
824 }
825 }
826
827 State state;
828
829 if(context->vertexShader)
830 {
John Bauman19bac1e2014-05-06 15:23:49 -0400831 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400832 }
833 else
834 {
John Bauman19bac1e2014-05-06 15:23:49 -0400835 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400836 }
837
838 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500839 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
John Bauman89401822014-05-06 15:04:28 -0400840 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
841 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500842
John Bauman89401822014-05-06 15:04:28 -0400843 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
844 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
845 state.vertexNormalActive = context->vertexNormalActive();
846 state.normalizeNormals = context->normalizeNormalsActive();
847 state.vertexLightingActive = context->vertexLightingActive();
848 state.diffuseActive = context->diffuseActive();
849 state.specularActive = context->specularActive();
850 state.vertexSpecularActive = context->vertexSpecularActive();
851
852 state.vertexLightActive = context->vertexLightActive(0) << 0 |
853 context->vertexLightActive(1) << 1 |
854 context->vertexLightActive(2) << 2 |
855 context->vertexLightActive(3) << 3 |
856 context->vertexLightActive(4) << 4 |
857 context->vertexLightActive(5) << 5 |
858 context->vertexLightActive(6) << 6 |
859 context->vertexLightActive(7) << 7;
860
861 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
862 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
863 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
864 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
865 state.fogActive = context->fogActive();
866 state.vertexFogMode = context->vertexFogModeActive();
867 state.rangeFogActive = context->rangeFogActive();
868 state.localViewerActive = context->localViewerActive();
869 state.pointSizeActive = context->pointSizeActive();
870 state.pointScaleActive = context->pointScaleActive();
871
872 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400873 state.superSampling = context->getSuperSampleCount() > 1;
874 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400875
Nicolas Capens0f250902015-06-25 15:25:29 -0400876 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400877 {
878 state.input[i].type = context->input[i].type;
879 state.input[i].count = context->input[i].count;
880 state.input[i].normalized = context->input[i].normalized;
881 }
882
883 if(!context->vertexShader)
884 {
885 for(int i = 0; i < 8; i++)
886 {
887 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
888 state.textureState[i].texGenActive = context->texGenActive(i);
889 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
890 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
891 }
892 }
893 else
894 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400895 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400896 {
897 if(context->vertexShader->usesSampler(i))
898 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400899 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400900 }
901 }
902 }
903
904 if(context->vertexShader) // FIXME: Also when pre-transformed?
905 {
906 for(int i = 0; i < 12; i++)
907 {
908 state.output[i].xWrite = context->vertexShader->output[i][0].active();
909 state.output[i].yWrite = context->vertexShader->output[i][1].active();
910 state.output[i].zWrite = context->vertexShader->output[i][2].active();
911 state.output[i].wWrite = context->vertexShader->output[i][3].active();
912 }
913 }
914 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
915 {
916 state.output[Pos].write = 0xF;
917
918 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
919 {
920 state.output[D0].write = 0xF;
921 }
Nicolas Capens2ca19032016-01-15 16:54:13 -0500922
John Bauman89401822014-05-06 15:04:28 -0400923 if(context->specularActive())
924 {
925 state.output[D1].write = 0xF;
926 }
927
928 for(int stage = 0; stage < 8; stage++)
929 {
John Bauman19bac1e2014-05-06 15:23:49 -0400930 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
931 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
932 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
933 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400934 }
935
936 if(context->fogActive())
937 {
938 state.output[Fog].xWrite = true;
939 }
940
941 if(context->pointSizeActive())
942 {
943 state.output[Pts].yWrite = true;
944 }
945 }
946 else
947 {
948 state.output[Pos].write = 0xF;
949
950 for(int i = 0; i < 2; i++)
951 {
952 if(context->input[Color0 + i])
953 {
954 state.output[D0 + i].write = 0xF;
955 }
956 }
957
958 for(int i = 0; i < 8; i++)
959 {
960 if(context->input[TexCoord0 + i])
961 {
962 state.output[T0 + i].write = 0xF;
963 }
964 }
965
John Bauman66b8ab22014-05-06 15:57:45 -0400966 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400967 {
968 state.output[Pts].yWrite = true;
969 }
970 }
971
972 if(context->vertexShaderVersion() < 0x0300)
973 {
974 state.output[D0].clamp = 0xF;
975 state.output[D1].clamp = 0xF;
976 state.output[Fog].xClamp = true;
977 }
978
979 state.hash = state.computeHash();
980
981 return state;
982 }
983
984 Routine *VertexProcessor::routine(const State &state)
985 {
986 Routine *routine = routineCache->query(state);
987
988 if(!routine) // Create one
989 {
990 VertexRoutine *generator = 0;
991
992 if(state.fixedFunction)
993 {
994 generator = new VertexPipeline(state);
995 }
996 else
997 {
998 generator = new VertexProgram(state, context->vertexShader);
999 }
1000
1001 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -05001002 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001003 delete generator;
1004
1005 routineCache->add(state, routine);
1006 }
1007
1008 return routine;
1009 }
1010}