blob: 73f277b06d5516ffc71a94b3b4769d8866725c4e [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "VertexProcessor.hpp"
16
John Bauman89401822014-05-06 15:04:28 -040017#include "Math.hpp"
18#include "VertexPipeline.hpp"
19#include "VertexProgram.hpp"
20#include "VertexShader.hpp"
21#include "PixelShader.hpp"
22#include "Constants.hpp"
23#include "Debug.hpp"
24
John Bauman66b8ab22014-05-06 15:57:45 -040025#include <string.h>
John Bauman89401822014-05-06 15:04:28 -040026
27namespace sw
28{
John Bauman66b8ab22014-05-06 15:57:45 -040029 bool precacheVertex = false;
30
John Bauman89401822014-05-06 15:04:28 -040031 void VertexCache::clear()
32 {
33 for(int i = 0; i < 16; i++)
34 {
35 tag[i] = 0x80000000;
36 }
37 }
38
39 unsigned int VertexProcessor::States::computeHash()
40 {
41 unsigned int *state = (unsigned int*)this;
42 unsigned int hash = 0;
43
Nicolas Capens5d961882016-01-01 23:18:14 -050044 for(unsigned int i = 0; i < sizeof(States) / 4; i++)
John Bauman89401822014-05-06 15:04:28 -040045 {
46 hash ^= state[i];
47 }
48
49 return hash;
50 }
51
52 VertexProcessor::State::State()
53 {
54 memset(this, 0, sizeof(State));
55 }
56
57 bool VertexProcessor::State::operator==(const State &state) const
58 {
59 if(hash != state.hash)
60 {
61 return false;
62 }
63
64 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
65 }
66
Alexis Hetu772d2492016-04-04 16:14:58 -040067 VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo()
68 {
Alexis Hetu772d2492016-04-04 16:14:58 -040069 buffer = nullptr;
70 offset = 0;
71 reg = 0;
72 row = 0;
73 col = 0;
74 stride = 0;
75 }
76
Alexis Hetuc6a57cb2016-04-07 10:48:31 -040077 VertexProcessor::UniformBufferInfo::UniformBufferInfo()
78 {
79 buffer = nullptr;
80 offset = 0;
81 }
82
John Bauman89401822014-05-06 15:04:28 -040083 VertexProcessor::VertexProcessor(Context *context) : context(context)
84 {
85 for(int i = 0; i < 12; i++)
86 {
87 M[i] = 1;
88 }
89
90 V = 1;
91 B = 1;
92 P = 0;
93 PB = 0;
94 PBV = 0;
Nicolas Capens2ca19032016-01-15 16:54:13 -050095
John Bauman89401822014-05-06 15:04:28 -040096 for(int i = 0; i < 12; i++)
97 {
98 PBVM[i] = 0;
99 }
100
101 setLightingEnable(true);
102 setSpecularEnable(false);
103
104 for(int i = 0; i < 8; i++)
105 {
106 setLightEnable(i, false);
107 setLightPosition(i, 0);
108 }
109
110 updateMatrix = true;
111 updateViewMatrix = true;
112 updateBaseMatrix = true;
113 updateProjectionMatrix = true;
114 updateLighting = true;
115
116 for(int i = 0; i < 12; i++)
117 {
118 updateModelMatrix[i] = true;
119 }
120
121 routineCache = 0;
122 setRoutineCacheSize(1024);
123 }
124
125 VertexProcessor::~VertexProcessor()
126 {
127 delete routineCache;
128 routineCache = 0;
129 }
130
131 void VertexProcessor::setInputStream(int index, const Stream &stream)
132 {
133 context->input[index] = stream;
134 }
135
John Bauman89401822014-05-06 15:04:28 -0400136 void VertexProcessor::resetInputStreams(bool preTransformed)
137 {
Nicolas Capensf0aef1a2016-05-18 14:44:21 -0400138 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400139 {
140 context->input[i].defaults();
141 }
142
143 context->preTransformed = preTransformed;
144 }
145
146 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
147 {
Alexis Hetu028f41b2016-01-13 14:40:47 -0500148 if(index < VERTEX_UNIFORM_VECTORS)
John Bauman89401822014-05-06 15:04:28 -0400149 {
150 c[index][0] = value[0];
151 c[index][1] = value[1];
152 c[index][2] = value[2];
153 c[index][3] = value[3];
154 }
155 else ASSERT(false);
156 }
157
158 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
159 {
160 if(index < 16)
161 {
162 i[index][0] = integer[0];
163 i[index][1] = integer[1];
164 i[index][2] = integer[2];
165 i[index][3] = integer[3];
166 }
167 else ASSERT(false);
168 }
169
170 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
171 {
172 if(index < 16)
173 {
174 b[index] = boolean != 0;
175 }
176 else ASSERT(false);
177 }
178
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400179 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
180 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400181 uniformBufferInfo[index].buffer = buffer;
182 uniformBufferInfo[index].offset = offset;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400183 }
184
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400185 void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400186 {
187 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
188 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400189 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
190 uniformBuffers[i] = uniformBufferInfo[i].buffer;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400191 }
192 }
193
Alexis Hetu772d2492016-04-04 16:14:58 -0400194 void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, size_t stride)
195 {
196 transformFeedbackInfo[index].buffer = buffer;
197 transformFeedbackInfo[index].offset = offset;
198 transformFeedbackInfo[index].reg = reg;
199 transformFeedbackInfo[index].row = row;
200 transformFeedbackInfo[index].col = col;
201 transformFeedbackInfo[index].stride = stride;
202 }
203
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400204 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 -0400205 {
206 for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
207 {
208 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 -0400209 transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer;
Alexis Hetu772d2492016-04-04 16:14:58 -0400210 v[i] = transformFeedbackInfo[i].reg;
211 r[i] = transformFeedbackInfo[i].row;
212 c[i] = transformFeedbackInfo[i].col;
213 s[i] = transformFeedbackInfo[i].stride;
214 }
215 }
216
John Bauman89401822014-05-06 15:04:28 -0400217 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
218 {
219 if(i < 12)
220 {
221 this->M[i] = M;
222
223 updateMatrix = true;
224 updateModelMatrix[i] = true;
225 updateLighting = true;
226 }
227 else ASSERT(false);
228 }
229
230 void VertexProcessor::setViewMatrix(const Matrix &V)
231 {
232 this->V = V;
233
234 updateMatrix = true;
235 updateViewMatrix = true;
236 }
237
238 void VertexProcessor::setBaseMatrix(const Matrix &B)
239 {
240 this->B = B;
241
242 updateMatrix = true;
243 updateBaseMatrix = true;
244 }
245
246 void VertexProcessor::setProjectionMatrix(const Matrix &P)
247 {
248 this->P = P;
249 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
250
251 updateMatrix = true;
252 updateProjectionMatrix = true;
253 }
254
255 void VertexProcessor::setLightingEnable(bool lightingEnable)
256 {
257 context->setLightingEnable(lightingEnable);
258
259 updateLighting = true;
260 }
261
262 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
263 {
264 if(light < 8)
265 {
266 context->setLightEnable(light, lightEnable);
267 }
268 else ASSERT(false);
269
270 updateLighting = true;
271 }
272
273 void VertexProcessor::setSpecularEnable(bool specularEnable)
274 {
275 context->setSpecularEnable(specularEnable);
276
277 updateLighting = true;
278 }
279
280 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
281 {
282 if(light < 8)
283 {
284 context->setLightPosition(light, lightPosition);
285 }
286 else ASSERT(false);
287
288 updateLighting = true;
289 }
290
291 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
292 {
293 if(light < 8)
294 {
295 ff.lightDiffuse[light][0] = lightDiffuse.r;
296 ff.lightDiffuse[light][1] = lightDiffuse.g;
297 ff.lightDiffuse[light][2] = lightDiffuse.b;
298 ff.lightDiffuse[light][3] = lightDiffuse.a;
299 }
300 else ASSERT(false);
301 }
302
303 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
304 {
305 if(light < 8)
306 {
307 ff.lightSpecular[light][0] = lightSpecular.r;
308 ff.lightSpecular[light][1] = lightSpecular.g;
309 ff.lightSpecular[light][2] = lightSpecular.b;
310 ff.lightSpecular[light][3] = lightSpecular.a;
311 }
312 else ASSERT(false);
313 }
314
315 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
316 {
317 if(light < 8)
318 {
319 ff.lightAmbient[light][0] = lightAmbient.r;
320 ff.lightAmbient[light][1] = lightAmbient.g;
321 ff.lightAmbient[light][2] = lightAmbient.b;
322 ff.lightAmbient[light][3] = lightAmbient.a;
323 }
324 else ASSERT(false);
325 }
326
327 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
328 {
329 if(light < 8)
330 {
Nicolas Capens2ca19032016-01-15 16:54:13 -0500331 ff.attenuationConstant[light] = replicate(constant);
John Bauman89401822014-05-06 15:04:28 -0400332 ff.attenuationLinear[light] = replicate(linear);
333 ff.attenuationQuadratic[light] = replicate(quadratic);
334 }
335 else ASSERT(false);
336 }
337
338 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
339 {
340 if(light < 8)
341 {
342 ff.lightRange[light] = lightRange;
343 }
344 else ASSERT(false);
345 }
346
347 void VertexProcessor::setFogEnable(bool fogEnable)
348 {
349 context->fogEnable = fogEnable;
350 }
351
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400352 void VertexProcessor::setVertexFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400353 {
354 context->vertexFogMode = fogMode;
355 }
356
Alexis Hetu6743bbf2015-04-21 17:06:14 -0400357 void VertexProcessor::setInstanceID(int instanceID)
358 {
359 context->instanceID = instanceID;
360 }
361
John Bauman89401822014-05-06 15:04:28 -0400362 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
363 {
364 context->setColorVertexEnable(colorVertexEnable);
365 }
366
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400367 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400368 {
369 context->setDiffuseMaterialSource(diffuseMaterialSource);
370 }
371
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400372 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400373 {
374 context->setSpecularMaterialSource(specularMaterialSource);
375 }
376
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400377 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400378 {
379 context->setAmbientMaterialSource(ambientMaterialSource);
380 }
381
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400382 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400383 {
384 context->setEmissiveMaterialSource(emissiveMaterialSource);
385 }
386
387 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
388 {
389 ff.globalAmbient[0] = globalAmbient.r;
390 ff.globalAmbient[1] = globalAmbient.g;
391 ff.globalAmbient[2] = globalAmbient.b;
392 ff.globalAmbient[3] = globalAmbient.a;
393 }
394
395 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
396 {
397 ff.materialEmission[0] = emission.r;
398 ff.materialEmission[1] = emission.g;
399 ff.materialEmission[2] = emission.b;
400 ff.materialEmission[3] = emission.a;
401 }
402
403 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
404 {
405 ff.materialAmbient[0] = materialAmbient.r;
406 ff.materialAmbient[1] = materialAmbient.g;
407 ff.materialAmbient[2] = materialAmbient.b;
408 ff.materialAmbient[3] = materialAmbient.a;
409 }
410
411 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
412 {
413 ff.materialDiffuse[0] = diffuseColor.r;
414 ff.materialDiffuse[1] = diffuseColor.g;
415 ff.materialDiffuse[2] = diffuseColor.b;
416 ff.materialDiffuse[3] = diffuseColor.a;
417 }
418
419 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
420 {
421 ff.materialSpecular[0] = specularColor.r;
422 ff.materialSpecular[1] = specularColor.g;
423 ff.materialSpecular[2] = specularColor.b;
424 ff.materialSpecular[3] = specularColor.a;
425 }
426
427 void VertexProcessor::setMaterialShininess(float specularPower)
428 {
429 ff.materialShininess = specularPower;
430 }
431
432 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
433 {
434 if(light < 8)
435 {
436 ff.lightPosition[light][0] = P.x;
437 ff.lightPosition[light][1] = P.y;
438 ff.lightPosition[light][2] = P.z;
439 ff.lightPosition[light][3] = 1;
440 }
441 else ASSERT(false);
442 }
443
444 void VertexProcessor::setRangeFogEnable(bool enable)
445 {
446 context->rangeFogEnable = enable;
447 }
448
449 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
450 {
451 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
452 }
453
454 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
455 {
456 if(vertexBlendMatrixCount <= 4)
457 {
458 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
459 }
460 else ASSERT(false);
461 }
462
463 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
464 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400465 if(stage < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400466 {
467 context->textureWrap[stage] = mask;
468 }
469 else ASSERT(false);
470
471 context->textureWrapActive = false;
472
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400473 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400474 {
475 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
476 }
477 }
478
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400479 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400480 {
481 if(stage < 8)
482 {
483 context->texGen[stage] = texGen;
484 }
485 else ASSERT(false);
486 }
487
488 void VertexProcessor::setLocalViewer(bool localViewer)
489 {
490 context->localViewer = localViewer;
491 }
492
493 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
494 {
495 context->normalizeNormals = normalizeNormals;
496 }
497
498 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
499 {
500 for(int i = 0; i < 4; i++)
501 {
502 for(int j = 0; j < 4; j++)
503 {
504 ff.textureTransform[stage][i][j] = T[i][j];
505 }
506 }
507 }
508
509 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
510 {
511 context->textureTransformCount[stage] = count;
512 context->textureTransformProject[stage] = project;
513 }
514
515 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
516 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400517 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400518 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400519 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
John Bauman89401822014-05-06 15:04:28 -0400520 }
521 else ASSERT(false);
522 }
523
524 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
525 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400526 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400527 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400528 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
John Bauman89401822014-05-06 15:04:28 -0400529 }
530 else ASSERT(false);
531 }
532
533 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
534 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400535 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400536 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400537 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
John Bauman89401822014-05-06 15:04:28 -0400538 }
539 else ASSERT(false);
540 }
541
542 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
543 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400544 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400545 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400546 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400547 }
548 else ASSERT(false);
549 }
550
551 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
552 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400553 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400554 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400555 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400556 }
557 else ASSERT(false);
558 }
559
560 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
561 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400562 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400563 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400564 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400565 }
566 else ASSERT(false);
567 }
568
569 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
570 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400571 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400572 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400573 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
John Bauman89401822014-05-06 15:04:28 -0400574 }
575 else ASSERT(false);
576 }
577
578 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
579 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400580 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400581 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400582 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
John Bauman89401822014-05-06 15:04:28 -0400583 }
584 else ASSERT(false);
585 }
586
587 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
588 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400589 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400590 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400591 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
John Bauman89401822014-05-06 15:04:28 -0400592 }
593 else ASSERT(false);
594 }
595
Alexis Hetu617a5d52014-11-13 10:56:20 -0500596 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400597 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400598 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400599 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400600 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
John Bauman89401822014-05-06 15:04:28 -0400601 }
602 else ASSERT(false);
603 }
604
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400605 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
606 {
607 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
608 {
609 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
610 }
611 else ASSERT(false);
612 }
613
614 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
615 {
616 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
617 {
618 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
619 }
620 else ASSERT(false);
621 }
622
623 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
624 {
625 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
626 {
627 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
628 }
629 else ASSERT(false);
630 }
631
632 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
633 {
634 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
635 {
636 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
637 }
638 else ASSERT(false);
639 }
640
John Bauman89401822014-05-06 15:04:28 -0400641 void VertexProcessor::setPointSize(float pointSize)
642 {
643 point.pointSize = replicate(pointSize);
644 }
645
646 void VertexProcessor::setPointSizeMin(float pointSizeMin)
647 {
648 point.pointSizeMin = pointSizeMin;
649 }
650
651 void VertexProcessor::setPointSizeMax(float pointSizeMax)
652 {
653 point.pointSizeMax = pointSizeMax;
654 }
655
656 void VertexProcessor::setPointScaleA(float pointScaleA)
657 {
658 point.pointScaleA = pointScaleA;
659 }
660
661 void VertexProcessor::setPointScaleB(float pointScaleB)
662 {
663 point.pointScaleB = pointScaleB;
664 }
665
666 void VertexProcessor::setPointScaleC(float pointScaleC)
667 {
668 point.pointScaleC = pointScaleC;
669 }
670
Alexis Hetu16116cb2016-03-02 15:59:51 -0500671 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
672 {
673 context->transformFeedbackQueryEnabled = enable;
674 }
675
676 void VertexProcessor::enableTransformFeedback(uint64_t enable)
677 {
678 context->transformFeedbackEnabled = enable;
679 }
680
John Bauman89401822014-05-06 15:04:28 -0400681 const Matrix &VertexProcessor::getModelTransform(int i)
682 {
683 updateTransform();
684 return PBVM[i];
685 }
686
687 const Matrix &VertexProcessor::getViewTransform()
688 {
689 updateTransform();
690 return PBV;
691 }
692
693 bool VertexProcessor::isFixedFunction()
694 {
695 return !context->vertexShader;
696 }
697
698 void VertexProcessor::setTransform(const Matrix &M, int i)
699 {
700 ff.transformT[i][0][0] = M[0][0];
701 ff.transformT[i][0][1] = M[1][0];
702 ff.transformT[i][0][2] = M[2][0];
703 ff.transformT[i][0][3] = M[3][0];
704
705 ff.transformT[i][1][0] = M[0][1];
706 ff.transformT[i][1][1] = M[1][1];
707 ff.transformT[i][1][2] = M[2][1];
708 ff.transformT[i][1][3] = M[3][1];
709
710 ff.transformT[i][2][0] = M[0][2];
711 ff.transformT[i][2][1] = M[1][2];
712 ff.transformT[i][2][2] = M[2][2];
713 ff.transformT[i][2][3] = M[3][2];
714
715 ff.transformT[i][3][0] = M[0][3];
716 ff.transformT[i][3][1] = M[1][3];
717 ff.transformT[i][3][2] = M[2][3];
718 ff.transformT[i][3][3] = M[3][3];
719 }
720
721 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
722 {
723 ff.cameraTransformT[i][0][0] = M[0][0];
724 ff.cameraTransformT[i][0][1] = M[1][0];
725 ff.cameraTransformT[i][0][2] = M[2][0];
726 ff.cameraTransformT[i][0][3] = M[3][0];
727
728 ff.cameraTransformT[i][1][0] = M[0][1];
729 ff.cameraTransformT[i][1][1] = M[1][1];
730 ff.cameraTransformT[i][1][2] = M[2][1];
731 ff.cameraTransformT[i][1][3] = M[3][1];
732
733 ff.cameraTransformT[i][2][0] = M[0][2];
734 ff.cameraTransformT[i][2][1] = M[1][2];
735 ff.cameraTransformT[i][2][2] = M[2][2];
736 ff.cameraTransformT[i][2][3] = M[3][2];
737
738 ff.cameraTransformT[i][3][0] = M[0][3];
739 ff.cameraTransformT[i][3][1] = M[1][3];
740 ff.cameraTransformT[i][3][2] = M[2][3];
741 ff.cameraTransformT[i][3][3] = M[3][3];
742 }
743
744 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
745 {
746 ff.normalTransformT[i][0][0] = M[0][0];
747 ff.normalTransformT[i][0][1] = M[1][0];
748 ff.normalTransformT[i][0][2] = M[2][0];
749 ff.normalTransformT[i][0][3] = M[3][0];
750
751 ff.normalTransformT[i][1][0] = M[0][1];
752 ff.normalTransformT[i][1][1] = M[1][1];
753 ff.normalTransformT[i][1][2] = M[2][1];
754 ff.normalTransformT[i][1][3] = M[3][1];
755
756 ff.normalTransformT[i][2][0] = M[0][2];
757 ff.normalTransformT[i][2][1] = M[1][2];
758 ff.normalTransformT[i][2][2] = M[2][2];
759 ff.normalTransformT[i][2][3] = M[3][2];
760
761 ff.normalTransformT[i][3][0] = M[0][3];
762 ff.normalTransformT[i][3][1] = M[1][3];
763 ff.normalTransformT[i][3][2] = M[2][3];
764 ff.normalTransformT[i][3][3] = M[3][3];
765 }
766
767 void VertexProcessor::updateTransform()
768 {
769 if(!updateMatrix) return;
770
771 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
772
773 if(updateProjectionMatrix)
774 {
775 PB = P * B;
776 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500777
John Bauman89401822014-05-06 15:04:28 -0400778 for(int i = 0; i < activeMatrices; i++)
779 {
780 PBVM[i] = PBV * M[i];
781 updateModelMatrix[i] = false;
782 }
783
784 updateProjectionMatrix = false;
785 updateBaseMatrix = false;
786 updateViewMatrix = false;
787 }
788
789 if(updateBaseMatrix)
790 {
791 PB = P * B;
792 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500793
John Bauman89401822014-05-06 15:04:28 -0400794 for(int i = 0; i < activeMatrices; i++)
795 {
796 PBVM[i] = PBV * M[i];
797 updateModelMatrix[i] = false;
798 }
799
800 updateBaseMatrix = false;
801 updateViewMatrix = false;
802 }
803
804 if(updateViewMatrix)
805 {
806 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500807
John Bauman89401822014-05-06 15:04:28 -0400808 for(int i = 0; i < activeMatrices; i++)
809 {
810 PBVM[i] = PBV * M[i];
811 updateModelMatrix[i] = false;
812 }
813
814 updateViewMatrix = false;
815 }
816
817 for(int i = 0; i < activeMatrices; i++)
818 {
819 if(updateModelMatrix[i])
820 {
821 PBVM[i] = PBV * M[i];
822 updateModelMatrix[i] = false;
823 }
824 }
825
826 for(int i = 0; i < activeMatrices; i++)
827 {
828 setTransform(PBVM[i], i);
829 setCameraTransform(B * V * M[i], i);
830 setNormalTransform(~!(B * V * M[i]), i);
831 }
832
833 updateMatrix = false;
834 }
835
836 void VertexProcessor::setRoutineCacheSize(int cacheSize)
837 {
838 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400839 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400840 }
841
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400842 const VertexProcessor::State VertexProcessor::update(DrawType drawType)
John Bauman89401822014-05-06 15:04:28 -0400843 {
844 if(isFixedFunction())
845 {
846 updateTransform();
847
848 if(updateLighting)
849 {
850 for(int i = 0; i < 8; i++)
851 {
852 if(context->vertexLightActive(i))
853 {
854 // Light position in camera coordinates
855 setLightViewPosition(i, B * V * context->getLightPosition(i));
856 }
857 }
858
859 updateLighting = false;
860 }
861 }
862
863 State state;
864
865 if(context->vertexShader)
866 {
John Bauman19bac1e2014-05-06 15:23:49 -0400867 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400868 }
869 else
870 {
John Bauman19bac1e2014-05-06 15:23:49 -0400871 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400872 }
873
874 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500875 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
John Bauman89401822014-05-06 15:04:28 -0400876 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
877 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500878
John Bauman89401822014-05-06 15:04:28 -0400879 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
880 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
881 state.vertexNormalActive = context->vertexNormalActive();
882 state.normalizeNormals = context->normalizeNormalsActive();
883 state.vertexLightingActive = context->vertexLightingActive();
884 state.diffuseActive = context->diffuseActive();
885 state.specularActive = context->specularActive();
886 state.vertexSpecularActive = context->vertexSpecularActive();
887
888 state.vertexLightActive = context->vertexLightActive(0) << 0 |
889 context->vertexLightActive(1) << 1 |
890 context->vertexLightActive(2) << 2 |
891 context->vertexLightActive(3) << 3 |
892 context->vertexLightActive(4) << 4 |
893 context->vertexLightActive(5) << 5 |
894 context->vertexLightActive(6) << 6 |
895 context->vertexLightActive(7) << 7;
896
897 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
898 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
899 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
900 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
901 state.fogActive = context->fogActive();
902 state.vertexFogMode = context->vertexFogModeActive();
903 state.rangeFogActive = context->rangeFogActive();
904 state.localViewerActive = context->localViewerActive();
905 state.pointSizeActive = context->pointSizeActive();
906 state.pointScaleActive = context->pointScaleActive();
907
908 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400909 state.superSampling = context->getSuperSampleCount() > 1;
910 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400911
Alexis Hetu16116cb2016-03-02 15:59:51 -0500912 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
913 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
914
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400915 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
916 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
917 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
918 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
919
Nicolas Capensf0aef1a2016-05-18 14:44:21 -0400920 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400921 {
922 state.input[i].type = context->input[i].type;
923 state.input[i].count = context->input[i].count;
924 state.input[i].normalized = context->input[i].normalized;
925 }
926
927 if(!context->vertexShader)
928 {
929 for(int i = 0; i < 8; i++)
930 {
931 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
932 state.textureState[i].texGenActive = context->texGenActive(i);
933 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
934 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
935 }
936 }
937 else
938 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400939 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400940 {
941 if(context->vertexShader->usesSampler(i))
942 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400943 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400944 }
945 }
946 }
947
948 if(context->vertexShader) // FIXME: Also when pre-transformed?
949 {
Nicolas Capensec0936c2016-05-18 12:32:02 -0400950 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400951 {
952 state.output[i].xWrite = context->vertexShader->output[i][0].active();
953 state.output[i].yWrite = context->vertexShader->output[i][1].active();
954 state.output[i].zWrite = context->vertexShader->output[i][2].active();
955 state.output[i].wWrite = context->vertexShader->output[i][3].active();
956 }
957 }
958 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
959 {
960 state.output[Pos].write = 0xF;
961
962 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
963 {
Nicolas Capens995ddea2016-05-17 11:48:56 -0400964 state.output[C0].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -0400965 }
Nicolas Capens2ca19032016-01-15 16:54:13 -0500966
John Bauman89401822014-05-06 15:04:28 -0400967 if(context->specularActive())
968 {
Nicolas Capens995ddea2016-05-17 11:48:56 -0400969 state.output[C1].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -0400970 }
971
972 for(int stage = 0; stage < 8; stage++)
973 {
John Bauman19bac1e2014-05-06 15:23:49 -0400974 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
975 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
976 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
977 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400978 }
979
980 if(context->fogActive())
981 {
982 state.output[Fog].xWrite = true;
983 }
984
985 if(context->pointSizeActive())
986 {
987 state.output[Pts].yWrite = true;
988 }
989 }
990 else
991 {
992 state.output[Pos].write = 0xF;
993
994 for(int i = 0; i < 2; i++)
995 {
996 if(context->input[Color0 + i])
997 {
Nicolas Capens995ddea2016-05-17 11:48:56 -0400998 state.output[C0 + i].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -0400999 }
1000 }
1001
1002 for(int i = 0; i < 8; i++)
1003 {
1004 if(context->input[TexCoord0 + i])
1005 {
1006 state.output[T0 + i].write = 0xF;
1007 }
1008 }
1009
John Bauman66b8ab22014-05-06 15:57:45 -04001010 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -04001011 {
1012 state.output[Pts].yWrite = true;
1013 }
1014 }
1015
1016 if(context->vertexShaderVersion() < 0x0300)
1017 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001018 state.output[C0].clamp = 0xF;
1019 state.output[C1].clamp = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001020 state.output[Fog].xClamp = true;
1021 }
1022
1023 state.hash = state.computeHash();
1024
1025 return state;
1026 }
1027
1028 Routine *VertexProcessor::routine(const State &state)
1029 {
1030 Routine *routine = routineCache->query(state);
1031
1032 if(!routine) // Create one
1033 {
1034 VertexRoutine *generator = 0;
1035
1036 if(state.fixedFunction)
1037 {
1038 generator = new VertexPipeline(state);
1039 }
1040 else
1041 {
1042 generator = new VertexProgram(state, context->vertexShader);
1043 }
1044
1045 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -05001046 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001047 delete generator;
1048
1049 routineCache->add(state, routine);
1050 }
1051
1052 return routine;
1053 }
1054}