blob: 6972d94ce7168b7a18bb39f703a9c1e2d9e0971f [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 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
Alexis Hetu95ac1872016-06-06 13:26:52 -0400650 void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
651 {
652 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
653 {
654 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
655 }
656 else ASSERT(false);
657 }
658
659 void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
660 {
661 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
662 {
663 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
664 }
665 else ASSERT(false);
666 }
667
Alexis Hetu112d81f2016-06-07 12:36:35 -0400668 void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
669 {
670 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
671 {
672 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
673 }
674 else ASSERT(false);
675 }
676
677 void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
678 {
679 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
680 {
681 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
682 }
683 else ASSERT(false);
684 }
685
John Bauman89401822014-05-06 15:04:28 -0400686 void VertexProcessor::setPointSize(float pointSize)
687 {
688 point.pointSize = replicate(pointSize);
689 }
690
691 void VertexProcessor::setPointSizeMin(float pointSizeMin)
692 {
693 point.pointSizeMin = pointSizeMin;
694 }
695
696 void VertexProcessor::setPointSizeMax(float pointSizeMax)
697 {
698 point.pointSizeMax = pointSizeMax;
699 }
700
701 void VertexProcessor::setPointScaleA(float pointScaleA)
702 {
703 point.pointScaleA = pointScaleA;
704 }
705
706 void VertexProcessor::setPointScaleB(float pointScaleB)
707 {
708 point.pointScaleB = pointScaleB;
709 }
710
711 void VertexProcessor::setPointScaleC(float pointScaleC)
712 {
713 point.pointScaleC = pointScaleC;
714 }
715
Alexis Hetu16116cb2016-03-02 15:59:51 -0500716 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
717 {
718 context->transformFeedbackQueryEnabled = enable;
719 }
720
721 void VertexProcessor::enableTransformFeedback(uint64_t enable)
722 {
723 context->transformFeedbackEnabled = enable;
724 }
725
John Bauman89401822014-05-06 15:04:28 -0400726 const Matrix &VertexProcessor::getModelTransform(int i)
727 {
728 updateTransform();
729 return PBVM[i];
730 }
731
732 const Matrix &VertexProcessor::getViewTransform()
733 {
734 updateTransform();
735 return PBV;
736 }
737
738 bool VertexProcessor::isFixedFunction()
739 {
740 return !context->vertexShader;
741 }
742
743 void VertexProcessor::setTransform(const Matrix &M, int i)
744 {
745 ff.transformT[i][0][0] = M[0][0];
746 ff.transformT[i][0][1] = M[1][0];
747 ff.transformT[i][0][2] = M[2][0];
748 ff.transformT[i][0][3] = M[3][0];
749
750 ff.transformT[i][1][0] = M[0][1];
751 ff.transformT[i][1][1] = M[1][1];
752 ff.transformT[i][1][2] = M[2][1];
753 ff.transformT[i][1][3] = M[3][1];
754
755 ff.transformT[i][2][0] = M[0][2];
756 ff.transformT[i][2][1] = M[1][2];
757 ff.transformT[i][2][2] = M[2][2];
758 ff.transformT[i][2][3] = M[3][2];
759
760 ff.transformT[i][3][0] = M[0][3];
761 ff.transformT[i][3][1] = M[1][3];
762 ff.transformT[i][3][2] = M[2][3];
763 ff.transformT[i][3][3] = M[3][3];
764 }
765
766 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
767 {
768 ff.cameraTransformT[i][0][0] = M[0][0];
769 ff.cameraTransformT[i][0][1] = M[1][0];
770 ff.cameraTransformT[i][0][2] = M[2][0];
771 ff.cameraTransformT[i][0][3] = M[3][0];
772
773 ff.cameraTransformT[i][1][0] = M[0][1];
774 ff.cameraTransformT[i][1][1] = M[1][1];
775 ff.cameraTransformT[i][1][2] = M[2][1];
776 ff.cameraTransformT[i][1][3] = M[3][1];
777
778 ff.cameraTransformT[i][2][0] = M[0][2];
779 ff.cameraTransformT[i][2][1] = M[1][2];
780 ff.cameraTransformT[i][2][2] = M[2][2];
781 ff.cameraTransformT[i][2][3] = M[3][2];
782
783 ff.cameraTransformT[i][3][0] = M[0][3];
784 ff.cameraTransformT[i][3][1] = M[1][3];
785 ff.cameraTransformT[i][3][2] = M[2][3];
786 ff.cameraTransformT[i][3][3] = M[3][3];
787 }
788
789 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
790 {
791 ff.normalTransformT[i][0][0] = M[0][0];
792 ff.normalTransformT[i][0][1] = M[1][0];
793 ff.normalTransformT[i][0][2] = M[2][0];
794 ff.normalTransformT[i][0][3] = M[3][0];
795
796 ff.normalTransformT[i][1][0] = M[0][1];
797 ff.normalTransformT[i][1][1] = M[1][1];
798 ff.normalTransformT[i][1][2] = M[2][1];
799 ff.normalTransformT[i][1][3] = M[3][1];
800
801 ff.normalTransformT[i][2][0] = M[0][2];
802 ff.normalTransformT[i][2][1] = M[1][2];
803 ff.normalTransformT[i][2][2] = M[2][2];
804 ff.normalTransformT[i][2][3] = M[3][2];
805
806 ff.normalTransformT[i][3][0] = M[0][3];
807 ff.normalTransformT[i][3][1] = M[1][3];
808 ff.normalTransformT[i][3][2] = M[2][3];
809 ff.normalTransformT[i][3][3] = M[3][3];
810 }
811
812 void VertexProcessor::updateTransform()
813 {
814 if(!updateMatrix) return;
815
816 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
817
818 if(updateProjectionMatrix)
819 {
820 PB = P * B;
821 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500822
John Bauman89401822014-05-06 15:04:28 -0400823 for(int i = 0; i < activeMatrices; i++)
824 {
825 PBVM[i] = PBV * M[i];
826 updateModelMatrix[i] = false;
827 }
828
829 updateProjectionMatrix = false;
830 updateBaseMatrix = false;
831 updateViewMatrix = false;
832 }
833
834 if(updateBaseMatrix)
835 {
836 PB = P * B;
837 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500838
John Bauman89401822014-05-06 15:04:28 -0400839 for(int i = 0; i < activeMatrices; i++)
840 {
841 PBVM[i] = PBV * M[i];
842 updateModelMatrix[i] = false;
843 }
844
845 updateBaseMatrix = false;
846 updateViewMatrix = false;
847 }
848
849 if(updateViewMatrix)
850 {
851 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500852
John Bauman89401822014-05-06 15:04:28 -0400853 for(int i = 0; i < activeMatrices; i++)
854 {
855 PBVM[i] = PBV * M[i];
856 updateModelMatrix[i] = false;
857 }
858
859 updateViewMatrix = false;
860 }
861
862 for(int i = 0; i < activeMatrices; i++)
863 {
864 if(updateModelMatrix[i])
865 {
866 PBVM[i] = PBV * M[i];
867 updateModelMatrix[i] = false;
868 }
869 }
870
871 for(int i = 0; i < activeMatrices; i++)
872 {
873 setTransform(PBVM[i], i);
874 setCameraTransform(B * V * M[i], i);
875 setNormalTransform(~!(B * V * M[i]), i);
876 }
877
878 updateMatrix = false;
879 }
880
881 void VertexProcessor::setRoutineCacheSize(int cacheSize)
882 {
883 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400884 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400885 }
886
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400887 const VertexProcessor::State VertexProcessor::update(DrawType drawType)
John Bauman89401822014-05-06 15:04:28 -0400888 {
889 if(isFixedFunction())
890 {
891 updateTransform();
892
893 if(updateLighting)
894 {
895 for(int i = 0; i < 8; i++)
896 {
897 if(context->vertexLightActive(i))
898 {
899 // Light position in camera coordinates
900 setLightViewPosition(i, B * V * context->getLightPosition(i));
901 }
902 }
903
904 updateLighting = false;
905 }
906 }
907
908 State state;
909
910 if(context->vertexShader)
911 {
John Bauman19bac1e2014-05-06 15:23:49 -0400912 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400913 }
914 else
915 {
John Bauman19bac1e2014-05-06 15:23:49 -0400916 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400917 }
918
919 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500920 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400921 state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
922 state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500923
John Bauman89401822014-05-06 15:04:28 -0400924 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
925 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
926 state.vertexNormalActive = context->vertexNormalActive();
927 state.normalizeNormals = context->normalizeNormalsActive();
928 state.vertexLightingActive = context->vertexLightingActive();
929 state.diffuseActive = context->diffuseActive();
930 state.specularActive = context->specularActive();
931 state.vertexSpecularActive = context->vertexSpecularActive();
932
933 state.vertexLightActive = context->vertexLightActive(0) << 0 |
934 context->vertexLightActive(1) << 1 |
935 context->vertexLightActive(2) << 2 |
936 context->vertexLightActive(3) << 3 |
937 context->vertexLightActive(4) << 4 |
938 context->vertexLightActive(5) << 5 |
939 context->vertexLightActive(6) << 6 |
940 context->vertexLightActive(7) << 7;
941
942 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
943 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
944 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
945 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
946 state.fogActive = context->fogActive();
947 state.vertexFogMode = context->vertexFogModeActive();
948 state.rangeFogActive = context->rangeFogActive();
949 state.localViewerActive = context->localViewerActive();
950 state.pointSizeActive = context->pointSizeActive();
951 state.pointScaleActive = context->pointScaleActive();
952
953 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400954 state.superSampling = context->getSuperSampleCount() > 1;
955 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400956
Alexis Hetu16116cb2016-03-02 15:59:51 -0500957 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
958 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
959
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400960 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
961 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
962 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
963 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
964
Nicolas Capensf0aef1a2016-05-18 14:44:21 -0400965 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400966 {
967 state.input[i].type = context->input[i].type;
968 state.input[i].count = context->input[i].count;
969 state.input[i].normalized = context->input[i].normalized;
Alexis Hetub7508b82016-09-22 15:36:45 -0400970 state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
John Bauman89401822014-05-06 15:04:28 -0400971 }
972
973 if(!context->vertexShader)
974 {
975 for(int i = 0; i < 8; i++)
976 {
977 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
978 state.textureState[i].texGenActive = context->texGenActive(i);
979 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
980 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
981 }
982 }
983 else
984 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400985 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400986 {
987 if(context->vertexShader->usesSampler(i))
988 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400989 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400990 }
991 }
992 }
993
994 if(context->vertexShader) // FIXME: Also when pre-transformed?
995 {
Nicolas Capensec0936c2016-05-18 12:32:02 -0400996 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400997 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400998 state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
999 state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
1000 state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
1001 state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
John Bauman89401822014-05-06 15:04:28 -04001002 }
1003 }
1004 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
1005 {
1006 state.output[Pos].write = 0xF;
1007
1008 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
1009 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001010 state.output[C0].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001011 }
Nicolas Capens2ca19032016-01-15 16:54:13 -05001012
John Bauman89401822014-05-06 15:04:28 -04001013 if(context->specularActive())
1014 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001015 state.output[C1].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001016 }
1017
1018 for(int stage = 0; stage < 8; stage++)
1019 {
John Bauman19bac1e2014-05-06 15:23:49 -04001020 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
1021 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
1022 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
1023 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -04001024 }
1025
1026 if(context->fogActive())
1027 {
1028 state.output[Fog].xWrite = true;
1029 }
1030
1031 if(context->pointSizeActive())
1032 {
1033 state.output[Pts].yWrite = true;
1034 }
1035 }
1036 else
1037 {
1038 state.output[Pos].write = 0xF;
1039
1040 for(int i = 0; i < 2; i++)
1041 {
1042 if(context->input[Color0 + i])
1043 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001044 state.output[C0 + i].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001045 }
1046 }
1047
1048 for(int i = 0; i < 8; i++)
1049 {
1050 if(context->input[TexCoord0 + i])
1051 {
1052 state.output[T0 + i].write = 0xF;
1053 }
1054 }
1055
John Bauman66b8ab22014-05-06 15:57:45 -04001056 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -04001057 {
1058 state.output[Pts].yWrite = true;
1059 }
1060 }
1061
1062 if(context->vertexShaderVersion() < 0x0300)
1063 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001064 state.output[C0].clamp = 0xF;
1065 state.output[C1].clamp = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001066 state.output[Fog].xClamp = true;
1067 }
1068
1069 state.hash = state.computeHash();
1070
1071 return state;
1072 }
1073
1074 Routine *VertexProcessor::routine(const State &state)
1075 {
1076 Routine *routine = routineCache->query(state);
1077
1078 if(!routine) // Create one
1079 {
Nicolas Capensccd5ecb2017-01-14 12:52:55 -05001080 VertexRoutine *generator = nullptr;
John Bauman89401822014-05-06 15:04:28 -04001081
1082 if(state.fixedFunction)
1083 {
1084 generator = new VertexPipeline(state);
1085 }
1086 else
1087 {
1088 generator = new VertexProgram(state, context->vertexShader);
1089 }
1090
1091 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -05001092 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001093 delete generator;
1094
1095 routineCache->add(state, routine);
1096 }
1097
1098 return routine;
1099 }
1100}