blob: a64c01091a9ac2b7583a89e1aaf05a87bf264731 [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 Hetu1d672442016-06-23 11:24:00 -0400194 void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, unsigned int stride)
Alexis Hetu772d2492016-04-04 16:14:58 -0400195 {
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
Alexis Hetu95ac1872016-06-06 13:26:52 -0400641 void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
642 {
643 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
644 {
645 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
646 }
647 else ASSERT(false);
648 }
649
650 void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
651 {
652 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
653 {
654 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
655 }
656 else ASSERT(false);
657 }
658
Alexis Hetu112d81f2016-06-07 12:36:35 -0400659 void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
660 {
661 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
662 {
663 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
664 }
665 else ASSERT(false);
666 }
667
668 void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
669 {
670 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
671 {
672 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
673 }
674 else ASSERT(false);
675 }
676
John Bauman89401822014-05-06 15:04:28 -0400677 void VertexProcessor::setPointSize(float pointSize)
678 {
679 point.pointSize = replicate(pointSize);
680 }
681
682 void VertexProcessor::setPointSizeMin(float pointSizeMin)
683 {
684 point.pointSizeMin = pointSizeMin;
685 }
686
687 void VertexProcessor::setPointSizeMax(float pointSizeMax)
688 {
689 point.pointSizeMax = pointSizeMax;
690 }
691
692 void VertexProcessor::setPointScaleA(float pointScaleA)
693 {
694 point.pointScaleA = pointScaleA;
695 }
696
697 void VertexProcessor::setPointScaleB(float pointScaleB)
698 {
699 point.pointScaleB = pointScaleB;
700 }
701
702 void VertexProcessor::setPointScaleC(float pointScaleC)
703 {
704 point.pointScaleC = pointScaleC;
705 }
706
Alexis Hetu16116cb2016-03-02 15:59:51 -0500707 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
708 {
709 context->transformFeedbackQueryEnabled = enable;
710 }
711
712 void VertexProcessor::enableTransformFeedback(uint64_t enable)
713 {
714 context->transformFeedbackEnabled = enable;
715 }
716
John Bauman89401822014-05-06 15:04:28 -0400717 const Matrix &VertexProcessor::getModelTransform(int i)
718 {
719 updateTransform();
720 return PBVM[i];
721 }
722
723 const Matrix &VertexProcessor::getViewTransform()
724 {
725 updateTransform();
726 return PBV;
727 }
728
729 bool VertexProcessor::isFixedFunction()
730 {
731 return !context->vertexShader;
732 }
733
734 void VertexProcessor::setTransform(const Matrix &M, int i)
735 {
736 ff.transformT[i][0][0] = M[0][0];
737 ff.transformT[i][0][1] = M[1][0];
738 ff.transformT[i][0][2] = M[2][0];
739 ff.transformT[i][0][3] = M[3][0];
740
741 ff.transformT[i][1][0] = M[0][1];
742 ff.transformT[i][1][1] = M[1][1];
743 ff.transformT[i][1][2] = M[2][1];
744 ff.transformT[i][1][3] = M[3][1];
745
746 ff.transformT[i][2][0] = M[0][2];
747 ff.transformT[i][2][1] = M[1][2];
748 ff.transformT[i][2][2] = M[2][2];
749 ff.transformT[i][2][3] = M[3][2];
750
751 ff.transformT[i][3][0] = M[0][3];
752 ff.transformT[i][3][1] = M[1][3];
753 ff.transformT[i][3][2] = M[2][3];
754 ff.transformT[i][3][3] = M[3][3];
755 }
756
757 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
758 {
759 ff.cameraTransformT[i][0][0] = M[0][0];
760 ff.cameraTransformT[i][0][1] = M[1][0];
761 ff.cameraTransformT[i][0][2] = M[2][0];
762 ff.cameraTransformT[i][0][3] = M[3][0];
763
764 ff.cameraTransformT[i][1][0] = M[0][1];
765 ff.cameraTransformT[i][1][1] = M[1][1];
766 ff.cameraTransformT[i][1][2] = M[2][1];
767 ff.cameraTransformT[i][1][3] = M[3][1];
768
769 ff.cameraTransformT[i][2][0] = M[0][2];
770 ff.cameraTransformT[i][2][1] = M[1][2];
771 ff.cameraTransformT[i][2][2] = M[2][2];
772 ff.cameraTransformT[i][2][3] = M[3][2];
773
774 ff.cameraTransformT[i][3][0] = M[0][3];
775 ff.cameraTransformT[i][3][1] = M[1][3];
776 ff.cameraTransformT[i][3][2] = M[2][3];
777 ff.cameraTransformT[i][3][3] = M[3][3];
778 }
779
780 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
781 {
782 ff.normalTransformT[i][0][0] = M[0][0];
783 ff.normalTransformT[i][0][1] = M[1][0];
784 ff.normalTransformT[i][0][2] = M[2][0];
785 ff.normalTransformT[i][0][3] = M[3][0];
786
787 ff.normalTransformT[i][1][0] = M[0][1];
788 ff.normalTransformT[i][1][1] = M[1][1];
789 ff.normalTransformT[i][1][2] = M[2][1];
790 ff.normalTransformT[i][1][3] = M[3][1];
791
792 ff.normalTransformT[i][2][0] = M[0][2];
793 ff.normalTransformT[i][2][1] = M[1][2];
794 ff.normalTransformT[i][2][2] = M[2][2];
795 ff.normalTransformT[i][2][3] = M[3][2];
796
797 ff.normalTransformT[i][3][0] = M[0][3];
798 ff.normalTransformT[i][3][1] = M[1][3];
799 ff.normalTransformT[i][3][2] = M[2][3];
800 ff.normalTransformT[i][3][3] = M[3][3];
801 }
802
803 void VertexProcessor::updateTransform()
804 {
805 if(!updateMatrix) return;
806
807 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
808
809 if(updateProjectionMatrix)
810 {
811 PB = P * B;
812 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500813
John Bauman89401822014-05-06 15:04:28 -0400814 for(int i = 0; i < activeMatrices; i++)
815 {
816 PBVM[i] = PBV * M[i];
817 updateModelMatrix[i] = false;
818 }
819
820 updateProjectionMatrix = false;
821 updateBaseMatrix = false;
822 updateViewMatrix = false;
823 }
824
825 if(updateBaseMatrix)
826 {
827 PB = P * B;
828 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500829
John Bauman89401822014-05-06 15:04:28 -0400830 for(int i = 0; i < activeMatrices; i++)
831 {
832 PBVM[i] = PBV * M[i];
833 updateModelMatrix[i] = false;
834 }
835
836 updateBaseMatrix = false;
837 updateViewMatrix = false;
838 }
839
840 if(updateViewMatrix)
841 {
842 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500843
John Bauman89401822014-05-06 15:04:28 -0400844 for(int i = 0; i < activeMatrices; i++)
845 {
846 PBVM[i] = PBV * M[i];
847 updateModelMatrix[i] = false;
848 }
849
850 updateViewMatrix = false;
851 }
852
853 for(int i = 0; i < activeMatrices; i++)
854 {
855 if(updateModelMatrix[i])
856 {
857 PBVM[i] = PBV * M[i];
858 updateModelMatrix[i] = false;
859 }
860 }
861
862 for(int i = 0; i < activeMatrices; i++)
863 {
864 setTransform(PBVM[i], i);
865 setCameraTransform(B * V * M[i], i);
866 setNormalTransform(~!(B * V * M[i]), i);
867 }
868
869 updateMatrix = false;
870 }
871
872 void VertexProcessor::setRoutineCacheSize(int cacheSize)
873 {
874 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400875 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400876 }
877
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400878 const VertexProcessor::State VertexProcessor::update(DrawType drawType)
John Bauman89401822014-05-06 15:04:28 -0400879 {
880 if(isFixedFunction())
881 {
882 updateTransform();
883
884 if(updateLighting)
885 {
886 for(int i = 0; i < 8; i++)
887 {
888 if(context->vertexLightActive(i))
889 {
890 // Light position in camera coordinates
891 setLightViewPosition(i, B * V * context->getLightPosition(i));
892 }
893 }
894
895 updateLighting = false;
896 }
897 }
898
899 State state;
900
901 if(context->vertexShader)
902 {
John Bauman19bac1e2014-05-06 15:23:49 -0400903 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400904 }
905 else
906 {
John Bauman19bac1e2014-05-06 15:23:49 -0400907 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400908 }
909
910 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500911 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400912 state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
913 state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500914
John Bauman89401822014-05-06 15:04:28 -0400915 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
916 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
917 state.vertexNormalActive = context->vertexNormalActive();
918 state.normalizeNormals = context->normalizeNormalsActive();
919 state.vertexLightingActive = context->vertexLightingActive();
920 state.diffuseActive = context->diffuseActive();
921 state.specularActive = context->specularActive();
922 state.vertexSpecularActive = context->vertexSpecularActive();
923
924 state.vertexLightActive = context->vertexLightActive(0) << 0 |
925 context->vertexLightActive(1) << 1 |
926 context->vertexLightActive(2) << 2 |
927 context->vertexLightActive(3) << 3 |
928 context->vertexLightActive(4) << 4 |
929 context->vertexLightActive(5) << 5 |
930 context->vertexLightActive(6) << 6 |
931 context->vertexLightActive(7) << 7;
932
933 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
934 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
935 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
936 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
937 state.fogActive = context->fogActive();
938 state.vertexFogMode = context->vertexFogModeActive();
939 state.rangeFogActive = context->rangeFogActive();
940 state.localViewerActive = context->localViewerActive();
941 state.pointSizeActive = context->pointSizeActive();
942 state.pointScaleActive = context->pointScaleActive();
943
944 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400945 state.superSampling = context->getSuperSampleCount() > 1;
946 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400947
Alexis Hetu16116cb2016-03-02 15:59:51 -0500948 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
949 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
950
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400951 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
952 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
953 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
954 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
955
Nicolas Capensf0aef1a2016-05-18 14:44:21 -0400956 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400957 {
958 state.input[i].type = context->input[i].type;
959 state.input[i].count = context->input[i].count;
960 state.input[i].normalized = context->input[i].normalized;
Alexis Hetub7508b82016-09-22 15:36:45 -0400961 state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
John Bauman89401822014-05-06 15:04:28 -0400962 }
963
964 if(!context->vertexShader)
965 {
966 for(int i = 0; i < 8; i++)
967 {
968 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
969 state.textureState[i].texGenActive = context->texGenActive(i);
970 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
971 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
972 }
973 }
974 else
975 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400976 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400977 {
978 if(context->vertexShader->usesSampler(i))
979 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400980 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400981 }
982 }
983 }
984
985 if(context->vertexShader) // FIXME: Also when pre-transformed?
986 {
Nicolas Capensec0936c2016-05-18 12:32:02 -0400987 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400988 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400989 state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
990 state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
991 state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
992 state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
John Bauman89401822014-05-06 15:04:28 -0400993 }
994 }
995 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
996 {
997 state.output[Pos].write = 0xF;
998
999 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
1000 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001001 state.output[C0].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001002 }
Nicolas Capens2ca19032016-01-15 16:54:13 -05001003
John Bauman89401822014-05-06 15:04:28 -04001004 if(context->specularActive())
1005 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001006 state.output[C1].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001007 }
1008
1009 for(int stage = 0; stage < 8; stage++)
1010 {
John Bauman19bac1e2014-05-06 15:23:49 -04001011 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
1012 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
1013 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
1014 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -04001015 }
1016
1017 if(context->fogActive())
1018 {
1019 state.output[Fog].xWrite = true;
1020 }
1021
1022 if(context->pointSizeActive())
1023 {
1024 state.output[Pts].yWrite = true;
1025 }
1026 }
1027 else
1028 {
1029 state.output[Pos].write = 0xF;
1030
1031 for(int i = 0; i < 2; i++)
1032 {
1033 if(context->input[Color0 + i])
1034 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001035 state.output[C0 + i].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001036 }
1037 }
1038
1039 for(int i = 0; i < 8; i++)
1040 {
1041 if(context->input[TexCoord0 + i])
1042 {
1043 state.output[T0 + i].write = 0xF;
1044 }
1045 }
1046
John Bauman66b8ab22014-05-06 15:57:45 -04001047 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -04001048 {
1049 state.output[Pts].yWrite = true;
1050 }
1051 }
1052
1053 if(context->vertexShaderVersion() < 0x0300)
1054 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001055 state.output[C0].clamp = 0xF;
1056 state.output[C1].clamp = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001057 state.output[Fog].xClamp = true;
1058 }
1059
1060 state.hash = state.computeHash();
1061
1062 return state;
1063 }
1064
1065 Routine *VertexProcessor::routine(const State &state)
1066 {
1067 Routine *routine = routineCache->query(state);
1068
1069 if(!routine) // Create one
1070 {
1071 VertexRoutine *generator = 0;
1072
1073 if(state.fixedFunction)
1074 {
1075 generator = new VertexPipeline(state);
1076 }
1077 else
1078 {
1079 generator = new VertexProgram(state, context->vertexShader);
1080 }
1081
1082 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -05001083 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001084 delete generator;
1085
1086 routineCache->add(state, routine);
1087 }
1088
1089 return routine;
1090 }
1091}