blob: eaaf3e2808a03f90417543d3800495c54de320a5 [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
Alexis Hetu16116cb2016-03-02 15:59:51 -0500645 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
646 {
647 context->transformFeedbackQueryEnabled = enable;
648 }
649
650 void VertexProcessor::enableTransformFeedback(uint64_t enable)
651 {
652 context->transformFeedbackEnabled = enable;
653 }
654
John Bauman89401822014-05-06 15:04:28 -0400655 const Matrix &VertexProcessor::getModelTransform(int i)
656 {
657 updateTransform();
658 return PBVM[i];
659 }
660
661 const Matrix &VertexProcessor::getViewTransform()
662 {
663 updateTransform();
664 return PBV;
665 }
666
667 bool VertexProcessor::isFixedFunction()
668 {
669 return !context->vertexShader;
670 }
671
672 void VertexProcessor::setTransform(const Matrix &M, int i)
673 {
674 ff.transformT[i][0][0] = M[0][0];
675 ff.transformT[i][0][1] = M[1][0];
676 ff.transformT[i][0][2] = M[2][0];
677 ff.transformT[i][0][3] = M[3][0];
678
679 ff.transformT[i][1][0] = M[0][1];
680 ff.transformT[i][1][1] = M[1][1];
681 ff.transformT[i][1][2] = M[2][1];
682 ff.transformT[i][1][3] = M[3][1];
683
684 ff.transformT[i][2][0] = M[0][2];
685 ff.transformT[i][2][1] = M[1][2];
686 ff.transformT[i][2][2] = M[2][2];
687 ff.transformT[i][2][3] = M[3][2];
688
689 ff.transformT[i][3][0] = M[0][3];
690 ff.transformT[i][3][1] = M[1][3];
691 ff.transformT[i][3][2] = M[2][3];
692 ff.transformT[i][3][3] = M[3][3];
693 }
694
695 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
696 {
697 ff.cameraTransformT[i][0][0] = M[0][0];
698 ff.cameraTransformT[i][0][1] = M[1][0];
699 ff.cameraTransformT[i][0][2] = M[2][0];
700 ff.cameraTransformT[i][0][3] = M[3][0];
701
702 ff.cameraTransformT[i][1][0] = M[0][1];
703 ff.cameraTransformT[i][1][1] = M[1][1];
704 ff.cameraTransformT[i][1][2] = M[2][1];
705 ff.cameraTransformT[i][1][3] = M[3][1];
706
707 ff.cameraTransformT[i][2][0] = M[0][2];
708 ff.cameraTransformT[i][2][1] = M[1][2];
709 ff.cameraTransformT[i][2][2] = M[2][2];
710 ff.cameraTransformT[i][2][3] = M[3][2];
711
712 ff.cameraTransformT[i][3][0] = M[0][3];
713 ff.cameraTransformT[i][3][1] = M[1][3];
714 ff.cameraTransformT[i][3][2] = M[2][3];
715 ff.cameraTransformT[i][3][3] = M[3][3];
716 }
717
718 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
719 {
720 ff.normalTransformT[i][0][0] = M[0][0];
721 ff.normalTransformT[i][0][1] = M[1][0];
722 ff.normalTransformT[i][0][2] = M[2][0];
723 ff.normalTransformT[i][0][3] = M[3][0];
724
725 ff.normalTransformT[i][1][0] = M[0][1];
726 ff.normalTransformT[i][1][1] = M[1][1];
727 ff.normalTransformT[i][1][2] = M[2][1];
728 ff.normalTransformT[i][1][3] = M[3][1];
729
730 ff.normalTransformT[i][2][0] = M[0][2];
731 ff.normalTransformT[i][2][1] = M[1][2];
732 ff.normalTransformT[i][2][2] = M[2][2];
733 ff.normalTransformT[i][2][3] = M[3][2];
734
735 ff.normalTransformT[i][3][0] = M[0][3];
736 ff.normalTransformT[i][3][1] = M[1][3];
737 ff.normalTransformT[i][3][2] = M[2][3];
738 ff.normalTransformT[i][3][3] = M[3][3];
739 }
740
741 void VertexProcessor::updateTransform()
742 {
743 if(!updateMatrix) return;
744
745 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
746
747 if(updateProjectionMatrix)
748 {
749 PB = P * B;
750 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500751
John Bauman89401822014-05-06 15:04:28 -0400752 for(int i = 0; i < activeMatrices; i++)
753 {
754 PBVM[i] = PBV * M[i];
755 updateModelMatrix[i] = false;
756 }
757
758 updateProjectionMatrix = false;
759 updateBaseMatrix = false;
760 updateViewMatrix = false;
761 }
762
763 if(updateBaseMatrix)
764 {
765 PB = P * B;
766 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500767
John Bauman89401822014-05-06 15:04:28 -0400768 for(int i = 0; i < activeMatrices; i++)
769 {
770 PBVM[i] = PBV * M[i];
771 updateModelMatrix[i] = false;
772 }
773
774 updateBaseMatrix = false;
775 updateViewMatrix = false;
776 }
777
778 if(updateViewMatrix)
779 {
780 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500781
John Bauman89401822014-05-06 15:04:28 -0400782 for(int i = 0; i < activeMatrices; i++)
783 {
784 PBVM[i] = PBV * M[i];
785 updateModelMatrix[i] = false;
786 }
787
788 updateViewMatrix = false;
789 }
790
791 for(int i = 0; i < activeMatrices; i++)
792 {
793 if(updateModelMatrix[i])
794 {
795 PBVM[i] = PBV * M[i];
796 updateModelMatrix[i] = false;
797 }
798 }
799
800 for(int i = 0; i < activeMatrices; i++)
801 {
802 setTransform(PBVM[i], i);
803 setCameraTransform(B * V * M[i], i);
804 setNormalTransform(~!(B * V * M[i]), i);
805 }
806
807 updateMatrix = false;
808 }
809
810 void VertexProcessor::setRoutineCacheSize(int cacheSize)
811 {
812 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400813 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400814 }
815
816 const VertexProcessor::State VertexProcessor::update()
817 {
818 if(isFixedFunction())
819 {
820 updateTransform();
821
822 if(updateLighting)
823 {
824 for(int i = 0; i < 8; i++)
825 {
826 if(context->vertexLightActive(i))
827 {
828 // Light position in camera coordinates
829 setLightViewPosition(i, B * V * context->getLightPosition(i));
830 }
831 }
832
833 updateLighting = false;
834 }
835 }
836
837 State state;
838
839 if(context->vertexShader)
840 {
John Bauman19bac1e2014-05-06 15:23:49 -0400841 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400842 }
843 else
844 {
John Bauman19bac1e2014-05-06 15:23:49 -0400845 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400846 }
847
848 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500849 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
John Bauman89401822014-05-06 15:04:28 -0400850 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
851 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500852
John Bauman89401822014-05-06 15:04:28 -0400853 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
854 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
855 state.vertexNormalActive = context->vertexNormalActive();
856 state.normalizeNormals = context->normalizeNormalsActive();
857 state.vertexLightingActive = context->vertexLightingActive();
858 state.diffuseActive = context->diffuseActive();
859 state.specularActive = context->specularActive();
860 state.vertexSpecularActive = context->vertexSpecularActive();
861
862 state.vertexLightActive = context->vertexLightActive(0) << 0 |
863 context->vertexLightActive(1) << 1 |
864 context->vertexLightActive(2) << 2 |
865 context->vertexLightActive(3) << 3 |
866 context->vertexLightActive(4) << 4 |
867 context->vertexLightActive(5) << 5 |
868 context->vertexLightActive(6) << 6 |
869 context->vertexLightActive(7) << 7;
870
871 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
872 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
873 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
874 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
875 state.fogActive = context->fogActive();
876 state.vertexFogMode = context->vertexFogModeActive();
877 state.rangeFogActive = context->rangeFogActive();
878 state.localViewerActive = context->localViewerActive();
879 state.pointSizeActive = context->pointSizeActive();
880 state.pointScaleActive = context->pointScaleActive();
881
882 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400883 state.superSampling = context->getSuperSampleCount() > 1;
884 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400885
Alexis Hetu16116cb2016-03-02 15:59:51 -0500886 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
887 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
888
Nicolas Capens0f250902015-06-25 15:25:29 -0400889 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400890 {
891 state.input[i].type = context->input[i].type;
892 state.input[i].count = context->input[i].count;
893 state.input[i].normalized = context->input[i].normalized;
894 }
895
896 if(!context->vertexShader)
897 {
898 for(int i = 0; i < 8; i++)
899 {
900 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
901 state.textureState[i].texGenActive = context->texGenActive(i);
902 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
903 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
904 }
905 }
906 else
907 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400908 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400909 {
910 if(context->vertexShader->usesSampler(i))
911 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400912 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400913 }
914 }
915 }
916
917 if(context->vertexShader) // FIXME: Also when pre-transformed?
918 {
919 for(int i = 0; i < 12; i++)
920 {
921 state.output[i].xWrite = context->vertexShader->output[i][0].active();
922 state.output[i].yWrite = context->vertexShader->output[i][1].active();
923 state.output[i].zWrite = context->vertexShader->output[i][2].active();
924 state.output[i].wWrite = context->vertexShader->output[i][3].active();
925 }
926 }
927 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
928 {
929 state.output[Pos].write = 0xF;
930
931 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
932 {
933 state.output[D0].write = 0xF;
934 }
Nicolas Capens2ca19032016-01-15 16:54:13 -0500935
John Bauman89401822014-05-06 15:04:28 -0400936 if(context->specularActive())
937 {
938 state.output[D1].write = 0xF;
939 }
940
941 for(int stage = 0; stage < 8; stage++)
942 {
John Bauman19bac1e2014-05-06 15:23:49 -0400943 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
944 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
945 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
946 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400947 }
948
949 if(context->fogActive())
950 {
951 state.output[Fog].xWrite = true;
952 }
953
954 if(context->pointSizeActive())
955 {
956 state.output[Pts].yWrite = true;
957 }
958 }
959 else
960 {
961 state.output[Pos].write = 0xF;
962
963 for(int i = 0; i < 2; i++)
964 {
965 if(context->input[Color0 + i])
966 {
967 state.output[D0 + i].write = 0xF;
968 }
969 }
970
971 for(int i = 0; i < 8; i++)
972 {
973 if(context->input[TexCoord0 + i])
974 {
975 state.output[T0 + i].write = 0xF;
976 }
977 }
978
John Bauman66b8ab22014-05-06 15:57:45 -0400979 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400980 {
981 state.output[Pts].yWrite = true;
982 }
983 }
984
985 if(context->vertexShaderVersion() < 0x0300)
986 {
987 state.output[D0].clamp = 0xF;
988 state.output[D1].clamp = 0xF;
989 state.output[Fog].xClamp = true;
990 }
991
992 state.hash = state.computeHash();
993
994 return state;
995 }
996
997 Routine *VertexProcessor::routine(const State &state)
998 {
999 Routine *routine = routineCache->query(state);
1000
1001 if(!routine) // Create one
1002 {
1003 VertexRoutine *generator = 0;
1004
1005 if(state.fixedFunction)
1006 {
1007 generator = new VertexPipeline(state);
1008 }
1009 else
1010 {
1011 generator = new VertexProgram(state, context->vertexShader);
1012 }
1013
1014 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -05001015 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001016 delete generator;
1017
1018 routineCache->add(state, routine);
1019 }
1020
1021 return routine;
1022 }
1023}