blob: 24f40cc4f51a798db286d898ac2bb444bbf39cfe [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
Alexis Hetu772d2492016-04-04 16:14:58 -040064 VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo()
65 {
Alexis Hetu772d2492016-04-04 16:14:58 -040066 buffer = nullptr;
67 offset = 0;
68 reg = 0;
69 row = 0;
70 col = 0;
71 stride = 0;
72 }
73
Alexis Hetuc6a57cb2016-04-07 10:48:31 -040074 VertexProcessor::UniformBufferInfo::UniformBufferInfo()
75 {
76 buffer = nullptr;
77 offset = 0;
78 }
79
John Bauman89401822014-05-06 15:04:28 -040080 VertexProcessor::VertexProcessor(Context *context) : context(context)
81 {
82 for(int i = 0; i < 12; i++)
83 {
84 M[i] = 1;
85 }
86
87 V = 1;
88 B = 1;
89 P = 0;
90 PB = 0;
91 PBV = 0;
Nicolas Capens2ca19032016-01-15 16:54:13 -050092
John Bauman89401822014-05-06 15:04:28 -040093 for(int i = 0; i < 12; i++)
94 {
95 PBVM[i] = 0;
96 }
97
98 setLightingEnable(true);
99 setSpecularEnable(false);
100
101 for(int i = 0; i < 8; i++)
102 {
103 setLightEnable(i, false);
104 setLightPosition(i, 0);
105 }
106
107 updateMatrix = true;
108 updateViewMatrix = true;
109 updateBaseMatrix = true;
110 updateProjectionMatrix = true;
111 updateLighting = true;
112
113 for(int i = 0; i < 12; i++)
114 {
115 updateModelMatrix[i] = true;
116 }
117
118 routineCache = 0;
119 setRoutineCacheSize(1024);
120 }
121
122 VertexProcessor::~VertexProcessor()
123 {
124 delete routineCache;
125 routineCache = 0;
126 }
127
128 void VertexProcessor::setInputStream(int index, const Stream &stream)
129 {
130 context->input[index] = stream;
131 }
132
John Bauman89401822014-05-06 15:04:28 -0400133 void VertexProcessor::resetInputStreams(bool preTransformed)
134 {
Nicolas Capens0f250902015-06-25 15:25:29 -0400135 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400136 {
137 context->input[i].defaults();
138 }
139
140 context->preTransformed = preTransformed;
141 }
142
143 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
144 {
Alexis Hetu028f41b2016-01-13 14:40:47 -0500145 if(index < VERTEX_UNIFORM_VECTORS)
John Bauman89401822014-05-06 15:04:28 -0400146 {
147 c[index][0] = value[0];
148 c[index][1] = value[1];
149 c[index][2] = value[2];
150 c[index][3] = value[3];
151 }
152 else ASSERT(false);
153 }
154
155 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
156 {
157 if(index < 16)
158 {
159 i[index][0] = integer[0];
160 i[index][1] = integer[1];
161 i[index][2] = integer[2];
162 i[index][3] = integer[3];
163 }
164 else ASSERT(false);
165 }
166
167 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
168 {
169 if(index < 16)
170 {
171 b[index] = boolean != 0;
172 }
173 else ASSERT(false);
174 }
175
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400176 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
177 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400178 uniformBufferInfo[index].buffer = buffer;
179 uniformBufferInfo[index].offset = offset;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400180 }
181
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400182 void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400183 {
184 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
185 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400186 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
187 uniformBuffers[i] = uniformBufferInfo[i].buffer;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400188 }
189 }
190
Alexis Hetu772d2492016-04-04 16:14:58 -0400191 void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, size_t stride)
192 {
193 transformFeedbackInfo[index].buffer = buffer;
194 transformFeedbackInfo[index].offset = offset;
195 transformFeedbackInfo[index].reg = reg;
196 transformFeedbackInfo[index].row = row;
197 transformFeedbackInfo[index].col = col;
198 transformFeedbackInfo[index].stride = stride;
199 }
200
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400201 void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[])
Alexis Hetu772d2492016-04-04 16:14:58 -0400202 {
203 for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
204 {
205 t[i] = transformFeedbackInfo[i].buffer ? static_cast<byte*>(transformFeedbackInfo[i].buffer->lock(PUBLIC, PRIVATE)) + transformFeedbackInfo[i].offset : nullptr;
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400206 transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer;
Alexis Hetu772d2492016-04-04 16:14:58 -0400207 v[i] = transformFeedbackInfo[i].reg;
208 r[i] = transformFeedbackInfo[i].row;
209 c[i] = transformFeedbackInfo[i].col;
210 s[i] = transformFeedbackInfo[i].stride;
211 }
212 }
213
John Bauman89401822014-05-06 15:04:28 -0400214 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
215 {
216 if(i < 12)
217 {
218 this->M[i] = M;
219
220 updateMatrix = true;
221 updateModelMatrix[i] = true;
222 updateLighting = true;
223 }
224 else ASSERT(false);
225 }
226
227 void VertexProcessor::setViewMatrix(const Matrix &V)
228 {
229 this->V = V;
230
231 updateMatrix = true;
232 updateViewMatrix = true;
233 }
234
235 void VertexProcessor::setBaseMatrix(const Matrix &B)
236 {
237 this->B = B;
238
239 updateMatrix = true;
240 updateBaseMatrix = true;
241 }
242
243 void VertexProcessor::setProjectionMatrix(const Matrix &P)
244 {
245 this->P = P;
246 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
247
248 updateMatrix = true;
249 updateProjectionMatrix = true;
250 }
251
252 void VertexProcessor::setLightingEnable(bool lightingEnable)
253 {
254 context->setLightingEnable(lightingEnable);
255
256 updateLighting = true;
257 }
258
259 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
260 {
261 if(light < 8)
262 {
263 context->setLightEnable(light, lightEnable);
264 }
265 else ASSERT(false);
266
267 updateLighting = true;
268 }
269
270 void VertexProcessor::setSpecularEnable(bool specularEnable)
271 {
272 context->setSpecularEnable(specularEnable);
273
274 updateLighting = true;
275 }
276
277 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
278 {
279 if(light < 8)
280 {
281 context->setLightPosition(light, lightPosition);
282 }
283 else ASSERT(false);
284
285 updateLighting = true;
286 }
287
288 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
289 {
290 if(light < 8)
291 {
292 ff.lightDiffuse[light][0] = lightDiffuse.r;
293 ff.lightDiffuse[light][1] = lightDiffuse.g;
294 ff.lightDiffuse[light][2] = lightDiffuse.b;
295 ff.lightDiffuse[light][3] = lightDiffuse.a;
296 }
297 else ASSERT(false);
298 }
299
300 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
301 {
302 if(light < 8)
303 {
304 ff.lightSpecular[light][0] = lightSpecular.r;
305 ff.lightSpecular[light][1] = lightSpecular.g;
306 ff.lightSpecular[light][2] = lightSpecular.b;
307 ff.lightSpecular[light][3] = lightSpecular.a;
308 }
309 else ASSERT(false);
310 }
311
312 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
313 {
314 if(light < 8)
315 {
316 ff.lightAmbient[light][0] = lightAmbient.r;
317 ff.lightAmbient[light][1] = lightAmbient.g;
318 ff.lightAmbient[light][2] = lightAmbient.b;
319 ff.lightAmbient[light][3] = lightAmbient.a;
320 }
321 else ASSERT(false);
322 }
323
324 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
325 {
326 if(light < 8)
327 {
Nicolas Capens2ca19032016-01-15 16:54:13 -0500328 ff.attenuationConstant[light] = replicate(constant);
John Bauman89401822014-05-06 15:04:28 -0400329 ff.attenuationLinear[light] = replicate(linear);
330 ff.attenuationQuadratic[light] = replicate(quadratic);
331 }
332 else ASSERT(false);
333 }
334
335 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
336 {
337 if(light < 8)
338 {
339 ff.lightRange[light] = lightRange;
340 }
341 else ASSERT(false);
342 }
343
344 void VertexProcessor::setFogEnable(bool fogEnable)
345 {
346 context->fogEnable = fogEnable;
347 }
348
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400349 void VertexProcessor::setVertexFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400350 {
351 context->vertexFogMode = fogMode;
352 }
353
Alexis Hetu6743bbf2015-04-21 17:06:14 -0400354 void VertexProcessor::setInstanceID(int instanceID)
355 {
356 context->instanceID = instanceID;
357 }
358
John Bauman89401822014-05-06 15:04:28 -0400359 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
360 {
361 context->setColorVertexEnable(colorVertexEnable);
362 }
363
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400364 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400365 {
366 context->setDiffuseMaterialSource(diffuseMaterialSource);
367 }
368
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400369 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400370 {
371 context->setSpecularMaterialSource(specularMaterialSource);
372 }
373
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400374 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400375 {
376 context->setAmbientMaterialSource(ambientMaterialSource);
377 }
378
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400379 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400380 {
381 context->setEmissiveMaterialSource(emissiveMaterialSource);
382 }
383
384 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
385 {
386 ff.globalAmbient[0] = globalAmbient.r;
387 ff.globalAmbient[1] = globalAmbient.g;
388 ff.globalAmbient[2] = globalAmbient.b;
389 ff.globalAmbient[3] = globalAmbient.a;
390 }
391
392 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
393 {
394 ff.materialEmission[0] = emission.r;
395 ff.materialEmission[1] = emission.g;
396 ff.materialEmission[2] = emission.b;
397 ff.materialEmission[3] = emission.a;
398 }
399
400 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
401 {
402 ff.materialAmbient[0] = materialAmbient.r;
403 ff.materialAmbient[1] = materialAmbient.g;
404 ff.materialAmbient[2] = materialAmbient.b;
405 ff.materialAmbient[3] = materialAmbient.a;
406 }
407
408 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
409 {
410 ff.materialDiffuse[0] = diffuseColor.r;
411 ff.materialDiffuse[1] = diffuseColor.g;
412 ff.materialDiffuse[2] = diffuseColor.b;
413 ff.materialDiffuse[3] = diffuseColor.a;
414 }
415
416 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
417 {
418 ff.materialSpecular[0] = specularColor.r;
419 ff.materialSpecular[1] = specularColor.g;
420 ff.materialSpecular[2] = specularColor.b;
421 ff.materialSpecular[3] = specularColor.a;
422 }
423
424 void VertexProcessor::setMaterialShininess(float specularPower)
425 {
426 ff.materialShininess = specularPower;
427 }
428
429 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
430 {
431 if(light < 8)
432 {
433 ff.lightPosition[light][0] = P.x;
434 ff.lightPosition[light][1] = P.y;
435 ff.lightPosition[light][2] = P.z;
436 ff.lightPosition[light][3] = 1;
437 }
438 else ASSERT(false);
439 }
440
441 void VertexProcessor::setRangeFogEnable(bool enable)
442 {
443 context->rangeFogEnable = enable;
444 }
445
446 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
447 {
448 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
449 }
450
451 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
452 {
453 if(vertexBlendMatrixCount <= 4)
454 {
455 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
456 }
457 else ASSERT(false);
458 }
459
460 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
461 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400462 if(stage < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400463 {
464 context->textureWrap[stage] = mask;
465 }
466 else ASSERT(false);
467
468 context->textureWrapActive = false;
469
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400470 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400471 {
472 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
473 }
474 }
475
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400476 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400477 {
478 if(stage < 8)
479 {
480 context->texGen[stage] = texGen;
481 }
482 else ASSERT(false);
483 }
484
485 void VertexProcessor::setLocalViewer(bool localViewer)
486 {
487 context->localViewer = localViewer;
488 }
489
490 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
491 {
492 context->normalizeNormals = normalizeNormals;
493 }
494
495 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
496 {
497 for(int i = 0; i < 4; i++)
498 {
499 for(int j = 0; j < 4; j++)
500 {
501 ff.textureTransform[stage][i][j] = T[i][j];
502 }
503 }
504 }
505
506 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
507 {
508 context->textureTransformCount[stage] = count;
509 context->textureTransformProject[stage] = project;
510 }
511
512 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
513 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400514 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400515 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400516 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
John Bauman89401822014-05-06 15:04:28 -0400517 }
518 else ASSERT(false);
519 }
520
521 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
522 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400523 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400524 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400525 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
John Bauman89401822014-05-06 15:04:28 -0400526 }
527 else ASSERT(false);
528 }
529
530 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
531 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400532 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400533 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400534 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
John Bauman89401822014-05-06 15:04:28 -0400535 }
536 else ASSERT(false);
537 }
538
539 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
540 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400541 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400542 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400543 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400544 }
545 else ASSERT(false);
546 }
547
548 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
549 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400550 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400551 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400552 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400553 }
554 else ASSERT(false);
555 }
556
557 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
558 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400559 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400560 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400561 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400562 }
563 else ASSERT(false);
564 }
565
566 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
567 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400568 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400569 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400570 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
John Bauman89401822014-05-06 15:04:28 -0400571 }
572 else ASSERT(false);
573 }
574
575 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
576 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400577 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400578 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400579 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
John Bauman89401822014-05-06 15:04:28 -0400580 }
581 else ASSERT(false);
582 }
583
584 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
585 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400586 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400587 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400588 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
John Bauman89401822014-05-06 15:04:28 -0400589 }
590 else ASSERT(false);
591 }
592
Alexis Hetu617a5d52014-11-13 10:56:20 -0500593 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400594 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400595 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400596 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400597 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
John Bauman89401822014-05-06 15:04:28 -0400598 }
599 else ASSERT(false);
600 }
601
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400602 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
603 {
604 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
605 {
606 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
607 }
608 else ASSERT(false);
609 }
610
611 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
612 {
613 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
614 {
615 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
616 }
617 else ASSERT(false);
618 }
619
620 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
621 {
622 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
623 {
624 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
625 }
626 else ASSERT(false);
627 }
628
629 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
630 {
631 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
632 {
633 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
634 }
635 else ASSERT(false);
636 }
637
John Bauman89401822014-05-06 15:04:28 -0400638 void VertexProcessor::setPointSize(float pointSize)
639 {
640 point.pointSize = replicate(pointSize);
641 }
642
643 void VertexProcessor::setPointSizeMin(float pointSizeMin)
644 {
645 point.pointSizeMin = pointSizeMin;
646 }
647
648 void VertexProcessor::setPointSizeMax(float pointSizeMax)
649 {
650 point.pointSizeMax = pointSizeMax;
651 }
652
653 void VertexProcessor::setPointScaleA(float pointScaleA)
654 {
655 point.pointScaleA = pointScaleA;
656 }
657
658 void VertexProcessor::setPointScaleB(float pointScaleB)
659 {
660 point.pointScaleB = pointScaleB;
661 }
662
663 void VertexProcessor::setPointScaleC(float pointScaleC)
664 {
665 point.pointScaleC = pointScaleC;
666 }
667
Alexis Hetu16116cb2016-03-02 15:59:51 -0500668 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
669 {
670 context->transformFeedbackQueryEnabled = enable;
671 }
672
673 void VertexProcessor::enableTransformFeedback(uint64_t enable)
674 {
675 context->transformFeedbackEnabled = enable;
676 }
677
John Bauman89401822014-05-06 15:04:28 -0400678 const Matrix &VertexProcessor::getModelTransform(int i)
679 {
680 updateTransform();
681 return PBVM[i];
682 }
683
684 const Matrix &VertexProcessor::getViewTransform()
685 {
686 updateTransform();
687 return PBV;
688 }
689
690 bool VertexProcessor::isFixedFunction()
691 {
692 return !context->vertexShader;
693 }
694
695 void VertexProcessor::setTransform(const Matrix &M, int i)
696 {
697 ff.transformT[i][0][0] = M[0][0];
698 ff.transformT[i][0][1] = M[1][0];
699 ff.transformT[i][0][2] = M[2][0];
700 ff.transformT[i][0][3] = M[3][0];
701
702 ff.transformT[i][1][0] = M[0][1];
703 ff.transformT[i][1][1] = M[1][1];
704 ff.transformT[i][1][2] = M[2][1];
705 ff.transformT[i][1][3] = M[3][1];
706
707 ff.transformT[i][2][0] = M[0][2];
708 ff.transformT[i][2][1] = M[1][2];
709 ff.transformT[i][2][2] = M[2][2];
710 ff.transformT[i][2][3] = M[3][2];
711
712 ff.transformT[i][3][0] = M[0][3];
713 ff.transformT[i][3][1] = M[1][3];
714 ff.transformT[i][3][2] = M[2][3];
715 ff.transformT[i][3][3] = M[3][3];
716 }
717
718 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
719 {
720 ff.cameraTransformT[i][0][0] = M[0][0];
721 ff.cameraTransformT[i][0][1] = M[1][0];
722 ff.cameraTransformT[i][0][2] = M[2][0];
723 ff.cameraTransformT[i][0][3] = M[3][0];
724
725 ff.cameraTransformT[i][1][0] = M[0][1];
726 ff.cameraTransformT[i][1][1] = M[1][1];
727 ff.cameraTransformT[i][1][2] = M[2][1];
728 ff.cameraTransformT[i][1][3] = M[3][1];
729
730 ff.cameraTransformT[i][2][0] = M[0][2];
731 ff.cameraTransformT[i][2][1] = M[1][2];
732 ff.cameraTransformT[i][2][2] = M[2][2];
733 ff.cameraTransformT[i][2][3] = M[3][2];
734
735 ff.cameraTransformT[i][3][0] = M[0][3];
736 ff.cameraTransformT[i][3][1] = M[1][3];
737 ff.cameraTransformT[i][3][2] = M[2][3];
738 ff.cameraTransformT[i][3][3] = M[3][3];
739 }
740
741 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
742 {
743 ff.normalTransformT[i][0][0] = M[0][0];
744 ff.normalTransformT[i][0][1] = M[1][0];
745 ff.normalTransformT[i][0][2] = M[2][0];
746 ff.normalTransformT[i][0][3] = M[3][0];
747
748 ff.normalTransformT[i][1][0] = M[0][1];
749 ff.normalTransformT[i][1][1] = M[1][1];
750 ff.normalTransformT[i][1][2] = M[2][1];
751 ff.normalTransformT[i][1][3] = M[3][1];
752
753 ff.normalTransformT[i][2][0] = M[0][2];
754 ff.normalTransformT[i][2][1] = M[1][2];
755 ff.normalTransformT[i][2][2] = M[2][2];
756 ff.normalTransformT[i][2][3] = M[3][2];
757
758 ff.normalTransformT[i][3][0] = M[0][3];
759 ff.normalTransformT[i][3][1] = M[1][3];
760 ff.normalTransformT[i][3][2] = M[2][3];
761 ff.normalTransformT[i][3][3] = M[3][3];
762 }
763
764 void VertexProcessor::updateTransform()
765 {
766 if(!updateMatrix) return;
767
768 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
769
770 if(updateProjectionMatrix)
771 {
772 PB = P * B;
773 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500774
John Bauman89401822014-05-06 15:04:28 -0400775 for(int i = 0; i < activeMatrices; i++)
776 {
777 PBVM[i] = PBV * M[i];
778 updateModelMatrix[i] = false;
779 }
780
781 updateProjectionMatrix = false;
782 updateBaseMatrix = false;
783 updateViewMatrix = false;
784 }
785
786 if(updateBaseMatrix)
787 {
788 PB = P * B;
789 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500790
John Bauman89401822014-05-06 15:04:28 -0400791 for(int i = 0; i < activeMatrices; i++)
792 {
793 PBVM[i] = PBV * M[i];
794 updateModelMatrix[i] = false;
795 }
796
797 updateBaseMatrix = false;
798 updateViewMatrix = false;
799 }
800
801 if(updateViewMatrix)
802 {
803 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500804
John Bauman89401822014-05-06 15:04:28 -0400805 for(int i = 0; i < activeMatrices; i++)
806 {
807 PBVM[i] = PBV * M[i];
808 updateModelMatrix[i] = false;
809 }
810
811 updateViewMatrix = false;
812 }
813
814 for(int i = 0; i < activeMatrices; i++)
815 {
816 if(updateModelMatrix[i])
817 {
818 PBVM[i] = PBV * M[i];
819 updateModelMatrix[i] = false;
820 }
821 }
822
823 for(int i = 0; i < activeMatrices; i++)
824 {
825 setTransform(PBVM[i], i);
826 setCameraTransform(B * V * M[i], i);
827 setNormalTransform(~!(B * V * M[i]), i);
828 }
829
830 updateMatrix = false;
831 }
832
833 void VertexProcessor::setRoutineCacheSize(int cacheSize)
834 {
835 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400836 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400837 }
838
839 const VertexProcessor::State VertexProcessor::update()
840 {
841 if(isFixedFunction())
842 {
843 updateTransform();
844
845 if(updateLighting)
846 {
847 for(int i = 0; i < 8; i++)
848 {
849 if(context->vertexLightActive(i))
850 {
851 // Light position in camera coordinates
852 setLightViewPosition(i, B * V * context->getLightPosition(i));
853 }
854 }
855
856 updateLighting = false;
857 }
858 }
859
860 State state;
861
862 if(context->vertexShader)
863 {
John Bauman19bac1e2014-05-06 15:23:49 -0400864 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400865 }
866 else
867 {
John Bauman19bac1e2014-05-06 15:23:49 -0400868 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400869 }
870
871 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500872 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
John Bauman89401822014-05-06 15:04:28 -0400873 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
874 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500875
John Bauman89401822014-05-06 15:04:28 -0400876 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
877 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
878 state.vertexNormalActive = context->vertexNormalActive();
879 state.normalizeNormals = context->normalizeNormalsActive();
880 state.vertexLightingActive = context->vertexLightingActive();
881 state.diffuseActive = context->diffuseActive();
882 state.specularActive = context->specularActive();
883 state.vertexSpecularActive = context->vertexSpecularActive();
884
885 state.vertexLightActive = context->vertexLightActive(0) << 0 |
886 context->vertexLightActive(1) << 1 |
887 context->vertexLightActive(2) << 2 |
888 context->vertexLightActive(3) << 3 |
889 context->vertexLightActive(4) << 4 |
890 context->vertexLightActive(5) << 5 |
891 context->vertexLightActive(6) << 6 |
892 context->vertexLightActive(7) << 7;
893
894 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
895 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
896 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
897 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
898 state.fogActive = context->fogActive();
899 state.vertexFogMode = context->vertexFogModeActive();
900 state.rangeFogActive = context->rangeFogActive();
901 state.localViewerActive = context->localViewerActive();
902 state.pointSizeActive = context->pointSizeActive();
903 state.pointScaleActive = context->pointScaleActive();
904
905 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400906 state.superSampling = context->getSuperSampleCount() > 1;
907 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400908
Alexis Hetu16116cb2016-03-02 15:59:51 -0500909 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
910 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
911
Nicolas Capens0f250902015-06-25 15:25:29 -0400912 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400913 {
914 state.input[i].type = context->input[i].type;
915 state.input[i].count = context->input[i].count;
916 state.input[i].normalized = context->input[i].normalized;
917 }
918
919 if(!context->vertexShader)
920 {
921 for(int i = 0; i < 8; i++)
922 {
923 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
924 state.textureState[i].texGenActive = context->texGenActive(i);
925 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
926 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
927 }
928 }
929 else
930 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400931 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400932 {
933 if(context->vertexShader->usesSampler(i))
934 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400935 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400936 }
937 }
938 }
939
940 if(context->vertexShader) // FIXME: Also when pre-transformed?
941 {
942 for(int i = 0; i < 12; i++)
943 {
944 state.output[i].xWrite = context->vertexShader->output[i][0].active();
945 state.output[i].yWrite = context->vertexShader->output[i][1].active();
946 state.output[i].zWrite = context->vertexShader->output[i][2].active();
947 state.output[i].wWrite = context->vertexShader->output[i][3].active();
948 }
949 }
950 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
951 {
952 state.output[Pos].write = 0xF;
953
954 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
955 {
956 state.output[D0].write = 0xF;
957 }
Nicolas Capens2ca19032016-01-15 16:54:13 -0500958
John Bauman89401822014-05-06 15:04:28 -0400959 if(context->specularActive())
960 {
961 state.output[D1].write = 0xF;
962 }
963
964 for(int stage = 0; stage < 8; stage++)
965 {
John Bauman19bac1e2014-05-06 15:23:49 -0400966 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
967 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
968 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
969 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400970 }
971
972 if(context->fogActive())
973 {
974 state.output[Fog].xWrite = true;
975 }
976
977 if(context->pointSizeActive())
978 {
979 state.output[Pts].yWrite = true;
980 }
981 }
982 else
983 {
984 state.output[Pos].write = 0xF;
985
986 for(int i = 0; i < 2; i++)
987 {
988 if(context->input[Color0 + i])
989 {
990 state.output[D0 + i].write = 0xF;
991 }
992 }
993
994 for(int i = 0; i < 8; i++)
995 {
996 if(context->input[TexCoord0 + i])
997 {
998 state.output[T0 + i].write = 0xF;
999 }
1000 }
1001
John Bauman66b8ab22014-05-06 15:57:45 -04001002 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -04001003 {
1004 state.output[Pts].yWrite = true;
1005 }
1006 }
1007
1008 if(context->vertexShaderVersion() < 0x0300)
1009 {
1010 state.output[D0].clamp = 0xF;
1011 state.output[D1].clamp = 0xF;
1012 state.output[Fog].xClamp = true;
1013 }
1014
1015 state.hash = state.computeHash();
1016
1017 return state;
1018 }
1019
1020 Routine *VertexProcessor::routine(const State &state)
1021 {
1022 Routine *routine = routineCache->query(state);
1023
1024 if(!routine) // Create one
1025 {
1026 VertexRoutine *generator = 0;
1027
1028 if(state.fixedFunction)
1029 {
1030 generator = new VertexPipeline(state);
1031 }
1032 else
1033 {
1034 generator = new VertexProgram(state, context->vertexShader);
1035 }
1036
1037 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -05001038 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001039 delete generator;
1040
1041 routineCache->add(state, routine);
1042 }
1043
1044 return routine;
1045 }
1046}