blob: 463393a50a79a8b5210a0e5b68f095021e09bdd5 [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
Nicolas Capens708c24b2017-10-26 13:07:10 -040017#include "Shader/VertexPipeline.hpp"
18#include "Shader/VertexProgram.hpp"
19#include "Shader/VertexShader.hpp"
20#include "Shader/PixelShader.hpp"
21#include "Shader/Constants.hpp"
22#include "Common/Math.hpp"
23#include "Common/Debug.hpp"
John Bauman89401822014-05-06 15:04:28 -040024
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 Hetu010a4642017-07-18 14:33:04 -0400605 void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
606 {
607 if(sampler < TEXTURE_IMAGE_UNITS)
608 {
609 context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
610 }
611 else ASSERT(false);
612 }
613
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400614 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
615 {
616 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
617 {
618 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
619 }
620 else ASSERT(false);
621 }
622
623 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
624 {
625 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
626 {
627 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
628 }
629 else ASSERT(false);
630 }
631
632 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
633 {
634 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
635 {
636 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
637 }
638 else ASSERT(false);
639 }
640
641 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
642 {
643 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
644 {
645 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
646 }
647 else ASSERT(false);
648 }
649
Nicolas Capensf878d502017-11-06 15:29:46 -0500650 void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
651 {
652 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
653 {
654 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
655 }
656 else ASSERT(false);
657 }
658
Alexis Hetu95ac1872016-06-06 13:26:52 -0400659 void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
660 {
661 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
662 {
663 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
664 }
665 else ASSERT(false);
666 }
667
668 void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
669 {
670 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
671 {
672 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
673 }
674 else ASSERT(false);
675 }
676
Alexis Hetu112d81f2016-06-07 12:36:35 -0400677 void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
678 {
679 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
680 {
681 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
682 }
683 else ASSERT(false);
684 }
685
686 void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
687 {
688 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
689 {
690 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
691 }
692 else ASSERT(false);
693 }
694
Alexis Hetu88482c32018-06-05 17:05:17 -0400695 void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
696 {
697 if(sampler < TEXTURE_IMAGE_UNITS)
698 {
699 context->sampler[sampler].setSyncRequired(isSincRequired);
700 }
701 else ASSERT(false);
702 }
703
John Bauman89401822014-05-06 15:04:28 -0400704 void VertexProcessor::setPointSize(float pointSize)
705 {
706 point.pointSize = replicate(pointSize);
707 }
708
709 void VertexProcessor::setPointSizeMin(float pointSizeMin)
710 {
711 point.pointSizeMin = pointSizeMin;
712 }
713
714 void VertexProcessor::setPointSizeMax(float pointSizeMax)
715 {
716 point.pointSizeMax = pointSizeMax;
717 }
718
719 void VertexProcessor::setPointScaleA(float pointScaleA)
720 {
721 point.pointScaleA = pointScaleA;
722 }
723
724 void VertexProcessor::setPointScaleB(float pointScaleB)
725 {
726 point.pointScaleB = pointScaleB;
727 }
728
729 void VertexProcessor::setPointScaleC(float pointScaleC)
730 {
731 point.pointScaleC = pointScaleC;
732 }
733
Alexis Hetu16116cb2016-03-02 15:59:51 -0500734 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
735 {
736 context->transformFeedbackQueryEnabled = enable;
737 }
738
739 void VertexProcessor::enableTransformFeedback(uint64_t enable)
740 {
741 context->transformFeedbackEnabled = enable;
742 }
743
John Bauman89401822014-05-06 15:04:28 -0400744 const Matrix &VertexProcessor::getModelTransform(int i)
745 {
746 updateTransform();
747 return PBVM[i];
748 }
749
750 const Matrix &VertexProcessor::getViewTransform()
751 {
752 updateTransform();
753 return PBV;
754 }
755
756 bool VertexProcessor::isFixedFunction()
757 {
758 return !context->vertexShader;
759 }
760
761 void VertexProcessor::setTransform(const Matrix &M, int i)
762 {
763 ff.transformT[i][0][0] = M[0][0];
764 ff.transformT[i][0][1] = M[1][0];
765 ff.transformT[i][0][2] = M[2][0];
766 ff.transformT[i][0][3] = M[3][0];
767
768 ff.transformT[i][1][0] = M[0][1];
769 ff.transformT[i][1][1] = M[1][1];
770 ff.transformT[i][1][2] = M[2][1];
771 ff.transformT[i][1][3] = M[3][1];
772
773 ff.transformT[i][2][0] = M[0][2];
774 ff.transformT[i][2][1] = M[1][2];
775 ff.transformT[i][2][2] = M[2][2];
776 ff.transformT[i][2][3] = M[3][2];
777
778 ff.transformT[i][3][0] = M[0][3];
779 ff.transformT[i][3][1] = M[1][3];
780 ff.transformT[i][3][2] = M[2][3];
781 ff.transformT[i][3][3] = M[3][3];
782 }
783
784 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
785 {
786 ff.cameraTransformT[i][0][0] = M[0][0];
787 ff.cameraTransformT[i][0][1] = M[1][0];
788 ff.cameraTransformT[i][0][2] = M[2][0];
789 ff.cameraTransformT[i][0][3] = M[3][0];
790
791 ff.cameraTransformT[i][1][0] = M[0][1];
792 ff.cameraTransformT[i][1][1] = M[1][1];
793 ff.cameraTransformT[i][1][2] = M[2][1];
794 ff.cameraTransformT[i][1][3] = M[3][1];
795
796 ff.cameraTransformT[i][2][0] = M[0][2];
797 ff.cameraTransformT[i][2][1] = M[1][2];
798 ff.cameraTransformT[i][2][2] = M[2][2];
799 ff.cameraTransformT[i][2][3] = M[3][2];
800
801 ff.cameraTransformT[i][3][0] = M[0][3];
802 ff.cameraTransformT[i][3][1] = M[1][3];
803 ff.cameraTransformT[i][3][2] = M[2][3];
804 ff.cameraTransformT[i][3][3] = M[3][3];
805 }
806
807 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
808 {
809 ff.normalTransformT[i][0][0] = M[0][0];
810 ff.normalTransformT[i][0][1] = M[1][0];
811 ff.normalTransformT[i][0][2] = M[2][0];
812 ff.normalTransformT[i][0][3] = M[3][0];
813
814 ff.normalTransformT[i][1][0] = M[0][1];
815 ff.normalTransformT[i][1][1] = M[1][1];
816 ff.normalTransformT[i][1][2] = M[2][1];
817 ff.normalTransformT[i][1][3] = M[3][1];
818
819 ff.normalTransformT[i][2][0] = M[0][2];
820 ff.normalTransformT[i][2][1] = M[1][2];
821 ff.normalTransformT[i][2][2] = M[2][2];
822 ff.normalTransformT[i][2][3] = M[3][2];
823
824 ff.normalTransformT[i][3][0] = M[0][3];
825 ff.normalTransformT[i][3][1] = M[1][3];
826 ff.normalTransformT[i][3][2] = M[2][3];
827 ff.normalTransformT[i][3][3] = M[3][3];
828 }
829
830 void VertexProcessor::updateTransform()
831 {
832 if(!updateMatrix) return;
833
834 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
835
836 if(updateProjectionMatrix)
837 {
838 PB = P * B;
839 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500840
John Bauman89401822014-05-06 15:04:28 -0400841 for(int i = 0; i < activeMatrices; i++)
842 {
843 PBVM[i] = PBV * M[i];
844 updateModelMatrix[i] = false;
845 }
846
847 updateProjectionMatrix = false;
848 updateBaseMatrix = false;
849 updateViewMatrix = false;
850 }
851
852 if(updateBaseMatrix)
853 {
854 PB = P * B;
855 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500856
John Bauman89401822014-05-06 15:04:28 -0400857 for(int i = 0; i < activeMatrices; i++)
858 {
859 PBVM[i] = PBV * M[i];
860 updateModelMatrix[i] = false;
861 }
862
863 updateBaseMatrix = false;
864 updateViewMatrix = false;
865 }
866
867 if(updateViewMatrix)
868 {
869 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500870
John Bauman89401822014-05-06 15:04:28 -0400871 for(int i = 0; i < activeMatrices; i++)
872 {
873 PBVM[i] = PBV * M[i];
874 updateModelMatrix[i] = false;
875 }
876
877 updateViewMatrix = false;
878 }
879
880 for(int i = 0; i < activeMatrices; i++)
881 {
882 if(updateModelMatrix[i])
883 {
884 PBVM[i] = PBV * M[i];
885 updateModelMatrix[i] = false;
886 }
887 }
888
889 for(int i = 0; i < activeMatrices; i++)
890 {
891 setTransform(PBVM[i], i);
892 setCameraTransform(B * V * M[i], i);
893 setNormalTransform(~!(B * V * M[i]), i);
894 }
895
896 updateMatrix = false;
897 }
898
899 void VertexProcessor::setRoutineCacheSize(int cacheSize)
900 {
901 delete routineCache;
Alexis Hetuf2878342019-03-12 16:32:04 -0400902 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536));
John Bauman89401822014-05-06 15:04:28 -0400903 }
904
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400905 const VertexProcessor::State VertexProcessor::update(DrawType drawType)
John Bauman89401822014-05-06 15:04:28 -0400906 {
907 if(isFixedFunction())
908 {
909 updateTransform();
910
911 if(updateLighting)
912 {
913 for(int i = 0; i < 8; i++)
914 {
915 if(context->vertexLightActive(i))
916 {
917 // Light position in camera coordinates
918 setLightViewPosition(i, B * V * context->getLightPosition(i));
919 }
920 }
921
922 updateLighting = false;
923 }
924 }
925
926 State state;
927
928 if(context->vertexShader)
929 {
John Bauman19bac1e2014-05-06 15:23:49 -0400930 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400931 }
932 else
933 {
John Bauman19bac1e2014-05-06 15:23:49 -0400934 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400935 }
936
Alexis Hetu53ad4af2017-12-06 14:49:07 -0500937 state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500938 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400939 state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
940 state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500941
John Bauman89401822014-05-06 15:04:28 -0400942 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
943 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
944 state.vertexNormalActive = context->vertexNormalActive();
945 state.normalizeNormals = context->normalizeNormalsActive();
946 state.vertexLightingActive = context->vertexLightingActive();
947 state.diffuseActive = context->diffuseActive();
948 state.specularActive = context->specularActive();
949 state.vertexSpecularActive = context->vertexSpecularActive();
950
951 state.vertexLightActive = context->vertexLightActive(0) << 0 |
952 context->vertexLightActive(1) << 1 |
953 context->vertexLightActive(2) << 2 |
954 context->vertexLightActive(3) << 3 |
955 context->vertexLightActive(4) << 4 |
956 context->vertexLightActive(5) << 5 |
957 context->vertexLightActive(6) << 6 |
958 context->vertexLightActive(7) << 7;
959
960 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
961 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
962 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
963 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
964 state.fogActive = context->fogActive();
965 state.vertexFogMode = context->vertexFogModeActive();
966 state.rangeFogActive = context->rangeFogActive();
967 state.localViewerActive = context->localViewerActive();
968 state.pointSizeActive = context->pointSizeActive();
969 state.pointScaleActive = context->pointScaleActive();
970
971 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400972 state.superSampling = context->getSuperSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400973
Alexis Hetu16116cb2016-03-02 15:59:51 -0500974 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
975 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
976
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400977 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
978 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
979 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
980 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
981
Nicolas Capensf0aef1a2016-05-18 14:44:21 -0400982 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400983 {
984 state.input[i].type = context->input[i].type;
985 state.input[i].count = context->input[i].count;
986 state.input[i].normalized = context->input[i].normalized;
Alexis Hetub7508b82016-09-22 15:36:45 -0400987 state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
John Bauman89401822014-05-06 15:04:28 -0400988 }
989
990 if(!context->vertexShader)
991 {
992 for(int i = 0; i < 8; i++)
993 {
994 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
995 state.textureState[i].texGenActive = context->texGenActive(i);
996 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
997 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
998 }
999 }
1000 else
1001 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -04001002 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -04001003 {
1004 if(context->vertexShader->usesSampler(i))
1005 {
Nicolas Capensf878d502017-11-06 15:29:46 -05001006 state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -04001007 }
1008 }
1009 }
1010
1011 if(context->vertexShader) // FIXME: Also when pre-transformed?
1012 {
Nicolas Capensec0936c2016-05-18 12:32:02 -04001013 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -04001014 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -04001015 state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
1016 state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
1017 state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
1018 state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
John Bauman89401822014-05-06 15:04:28 -04001019 }
1020 }
Alexis Hetu53ad4af2017-12-06 14:49:07 -05001021 else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
John Bauman89401822014-05-06 15:04:28 -04001022 {
1023 state.output[Pos].write = 0xF;
1024
1025 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
1026 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001027 state.output[C0].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001028 }
Nicolas Capens2ca19032016-01-15 16:54:13 -05001029
John Bauman89401822014-05-06 15:04:28 -04001030 if(context->specularActive())
1031 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001032 state.output[C1].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001033 }
1034
1035 for(int stage = 0; stage < 8; stage++)
1036 {
John Bauman19bac1e2014-05-06 15:23:49 -04001037 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
1038 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
1039 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
1040 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -04001041 }
1042
1043 if(context->fogActive())
1044 {
1045 state.output[Fog].xWrite = true;
1046 }
1047
1048 if(context->pointSizeActive())
1049 {
1050 state.output[Pts].yWrite = true;
1051 }
1052 }
1053 else
1054 {
1055 state.output[Pos].write = 0xF;
1056
1057 for(int i = 0; i < 2; i++)
1058 {
1059 if(context->input[Color0 + i])
1060 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001061 state.output[C0 + i].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001062 }
1063 }
1064
1065 for(int i = 0; i < 8; i++)
1066 {
1067 if(context->input[TexCoord0 + i])
1068 {
1069 state.output[T0 + i].write = 0xF;
1070 }
1071 }
1072
John Bauman66b8ab22014-05-06 15:57:45 -04001073 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -04001074 {
1075 state.output[Pts].yWrite = true;
1076 }
1077 }
1078
Alexis Hetu53ad4af2017-12-06 14:49:07 -05001079 if(context->vertexShaderModel() < 0x0300)
John Bauman89401822014-05-06 15:04:28 -04001080 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001081 state.output[C0].clamp = 0xF;
1082 state.output[C1].clamp = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001083 state.output[Fog].xClamp = true;
1084 }
1085
1086 state.hash = state.computeHash();
1087
1088 return state;
1089 }
1090
1091 Routine *VertexProcessor::routine(const State &state)
1092 {
1093 Routine *routine = routineCache->query(state);
1094
1095 if(!routine) // Create one
1096 {
Nicolas Capensccd5ecb2017-01-14 12:52:55 -05001097 VertexRoutine *generator = nullptr;
John Bauman89401822014-05-06 15:04:28 -04001098
1099 if(state.fixedFunction)
1100 {
1101 generator = new VertexPipeline(state);
1102 }
1103 else
1104 {
1105 generator = new VertexProgram(state, context->vertexShader);
1106 }
1107
1108 generator->generate();
Chris Forbes878d4b02019-01-21 10:48:35 -08001109 routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001110 delete generator;
1111
1112 routineCache->add(state, routine);
1113 }
1114
1115 return routine;
1116 }
1117}