blob: 0020d747c88e4f4bf32131ce3cf439c6cd3c5469 [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"
Nicolas Capens532770b2021-01-21 13:34:33 -050023#include "Common/Memory.hpp"
Nicolas Capens708c24b2017-10-26 13:07:10 -040024#include "Common/Debug.hpp"
John Bauman89401822014-05-06 15:04:28 -040025
Nicolas Capens92eb0412019-08-20 14:13:17 -040026#include <cstring>
John Bauman89401822014-05-06 15:04:28 -040027
28namespace sw
29{
John Bauman66b8ab22014-05-06 15:57:45 -040030 bool precacheVertex = false;
31
John Bauman89401822014-05-06 15:04:28 -040032 void VertexCache::clear()
33 {
34 for(int i = 0; i < 16; i++)
35 {
36 tag[i] = 0x80000000;
37 }
38 }
39
Nicolas Capens92eb0412019-08-20 14:13:17 -040040 uint32_t VertexProcessor::States::computeHash()
John Bauman89401822014-05-06 15:04:28 -040041 {
Nicolas Capens92eb0412019-08-20 14:13:17 -040042 uint32_t *state = reinterpret_cast<uint32_t*>(this);
43 uint32_t hash = 0;
John Bauman89401822014-05-06 15:04:28 -040044
Nicolas Capens92eb0412019-08-20 14:13:17 -040045 for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++)
John Bauman89401822014-05-06 15:04:28 -040046 {
47 hash ^= state[i];
48 }
49
50 return hash;
51 }
52
John Bauman89401822014-05-06 15:04:28 -040053 bool VertexProcessor::State::operator==(const State &state) const
54 {
55 if(hash != state.hash)
56 {
57 return false;
58 }
59
Nicolas Capens92eb0412019-08-20 14:13:17 -040060 static_assert(is_memcmparable<State>::value, "Cannot memcmp States");
John Bauman89401822014-05-06 15:04:28 -040061 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
62 }
63
Alexis Hetu772d2492016-04-04 16:14:58 -040064 VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo()
65 {
Alexis Hetu772d2492016-04-04 16:14:58 -040066 buffer = nullptr;
67 offset = 0;
68 reg = 0;
69 row = 0;
70 col = 0;
71 stride = 0;
72 }
73
Alexis Hetuc6a57cb2016-04-07 10:48:31 -040074 VertexProcessor::UniformBufferInfo::UniformBufferInfo()
75 {
76 buffer = nullptr;
77 offset = 0;
78 }
79
John Bauman89401822014-05-06 15:04:28 -040080 VertexProcessor::VertexProcessor(Context *context) : context(context)
81 {
82 for(int i = 0; i < 12; i++)
83 {
84 M[i] = 1;
85 }
86
87 V = 1;
88 B = 1;
89 P = 0;
90 PB = 0;
91 PBV = 0;
Nicolas Capens2ca19032016-01-15 16:54:13 -050092
John Bauman89401822014-05-06 15:04:28 -040093 for(int i = 0; i < 12; i++)
94 {
95 PBVM[i] = 0;
96 }
97
98 setLightingEnable(true);
99 setSpecularEnable(false);
100
101 for(int i = 0; i < 8; i++)
102 {
103 setLightEnable(i, false);
104 setLightPosition(i, 0);
105 }
106
107 updateMatrix = true;
108 updateViewMatrix = true;
109 updateBaseMatrix = true;
110 updateProjectionMatrix = true;
111 updateLighting = true;
112
113 for(int i = 0; i < 12; i++)
114 {
115 updateModelMatrix[i] = true;
116 }
117
Nicolas Capens92eb0412019-08-20 14:13:17 -0400118 routineCache = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400119 setRoutineCacheSize(1024);
120 }
121
122 VertexProcessor::~VertexProcessor()
123 {
124 delete routineCache;
Nicolas Capens92eb0412019-08-20 14:13:17 -0400125 routineCache = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400126 }
127
Nicolas Capens532770b2021-01-21 13:34:33 -0500128 // This object has to be mem aligned
129 void *VertexProcessor::operator new(size_t size)
130 {
131 ASSERT(size == sizeof(VertexProcessor)); // This operator can't be called from a derived class
132 return sw::allocate(sizeof(VertexProcessor), 16);
133 }
134
135 void VertexProcessor::operator delete(void *mem)
136 {
137 sw::deallocate(mem);
138 }
139
John Bauman89401822014-05-06 15:04:28 -0400140 void VertexProcessor::setInputStream(int index, const Stream &stream)
141 {
142 context->input[index] = stream;
143 }
144
John Bauman89401822014-05-06 15:04:28 -0400145 void VertexProcessor::resetInputStreams(bool preTransformed)
146 {
Nicolas Capensf0aef1a2016-05-18 14:44:21 -0400147 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400148 {
149 context->input[i].defaults();
150 }
151
152 context->preTransformed = preTransformed;
153 }
154
155 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
156 {
Alexis Hetu028f41b2016-01-13 14:40:47 -0500157 if(index < VERTEX_UNIFORM_VECTORS)
John Bauman89401822014-05-06 15:04:28 -0400158 {
159 c[index][0] = value[0];
160 c[index][1] = value[1];
161 c[index][2] = value[2];
162 c[index][3] = value[3];
163 }
164 else ASSERT(false);
165 }
166
167 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
168 {
169 if(index < 16)
170 {
171 i[index][0] = integer[0];
172 i[index][1] = integer[1];
173 i[index][2] = integer[2];
174 i[index][3] = integer[3];
175 }
176 else ASSERT(false);
177 }
178
179 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
180 {
181 if(index < 16)
182 {
183 b[index] = boolean != 0;
184 }
185 else ASSERT(false);
186 }
187
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400188 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
189 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400190 uniformBufferInfo[index].buffer = buffer;
191 uniformBufferInfo[index].offset = offset;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400192 }
193
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400194 void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400195 {
196 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
197 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400198 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
199 uniformBuffers[i] = uniformBufferInfo[i].buffer;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400200 }
201 }
202
Alexis Hetu1d672442016-06-23 11:24:00 -0400203 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 -0400204 {
205 transformFeedbackInfo[index].buffer = buffer;
206 transformFeedbackInfo[index].offset = offset;
207 transformFeedbackInfo[index].reg = reg;
208 transformFeedbackInfo[index].row = row;
209 transformFeedbackInfo[index].col = col;
210 transformFeedbackInfo[index].stride = stride;
211 }
212
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400213 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 -0400214 {
215 for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
216 {
217 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 -0400218 transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer;
Alexis Hetu772d2492016-04-04 16:14:58 -0400219 v[i] = transformFeedbackInfo[i].reg;
220 r[i] = transformFeedbackInfo[i].row;
221 c[i] = transformFeedbackInfo[i].col;
222 s[i] = transformFeedbackInfo[i].stride;
223 }
224 }
225
John Bauman89401822014-05-06 15:04:28 -0400226 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
227 {
228 if(i < 12)
229 {
230 this->M[i] = M;
231
232 updateMatrix = true;
233 updateModelMatrix[i] = true;
234 updateLighting = true;
235 }
236 else ASSERT(false);
237 }
238
239 void VertexProcessor::setViewMatrix(const Matrix &V)
240 {
241 this->V = V;
242
243 updateMatrix = true;
244 updateViewMatrix = true;
245 }
246
247 void VertexProcessor::setBaseMatrix(const Matrix &B)
248 {
249 this->B = B;
250
251 updateMatrix = true;
252 updateBaseMatrix = true;
253 }
254
255 void VertexProcessor::setProjectionMatrix(const Matrix &P)
256 {
257 this->P = P;
258 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
259
260 updateMatrix = true;
261 updateProjectionMatrix = true;
262 }
263
264 void VertexProcessor::setLightingEnable(bool lightingEnable)
265 {
266 context->setLightingEnable(lightingEnable);
267
268 updateLighting = true;
269 }
270
271 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
272 {
273 if(light < 8)
274 {
275 context->setLightEnable(light, lightEnable);
276 }
277 else ASSERT(false);
278
279 updateLighting = true;
280 }
281
282 void VertexProcessor::setSpecularEnable(bool specularEnable)
283 {
284 context->setSpecularEnable(specularEnable);
285
286 updateLighting = true;
287 }
288
289 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
290 {
291 if(light < 8)
292 {
293 context->setLightPosition(light, lightPosition);
294 }
295 else ASSERT(false);
296
297 updateLighting = true;
298 }
299
300 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
301 {
302 if(light < 8)
303 {
304 ff.lightDiffuse[light][0] = lightDiffuse.r;
305 ff.lightDiffuse[light][1] = lightDiffuse.g;
306 ff.lightDiffuse[light][2] = lightDiffuse.b;
307 ff.lightDiffuse[light][3] = lightDiffuse.a;
308 }
309 else ASSERT(false);
310 }
311
312 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
313 {
314 if(light < 8)
315 {
316 ff.lightSpecular[light][0] = lightSpecular.r;
317 ff.lightSpecular[light][1] = lightSpecular.g;
318 ff.lightSpecular[light][2] = lightSpecular.b;
319 ff.lightSpecular[light][3] = lightSpecular.a;
320 }
321 else ASSERT(false);
322 }
323
324 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
325 {
326 if(light < 8)
327 {
328 ff.lightAmbient[light][0] = lightAmbient.r;
329 ff.lightAmbient[light][1] = lightAmbient.g;
330 ff.lightAmbient[light][2] = lightAmbient.b;
331 ff.lightAmbient[light][3] = lightAmbient.a;
332 }
333 else ASSERT(false);
334 }
335
336 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
337 {
338 if(light < 8)
339 {
Nicolas Capens2ca19032016-01-15 16:54:13 -0500340 ff.attenuationConstant[light] = replicate(constant);
John Bauman89401822014-05-06 15:04:28 -0400341 ff.attenuationLinear[light] = replicate(linear);
342 ff.attenuationQuadratic[light] = replicate(quadratic);
343 }
344 else ASSERT(false);
345 }
346
347 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
348 {
349 if(light < 8)
350 {
351 ff.lightRange[light] = lightRange;
352 }
353 else ASSERT(false);
354 }
355
356 void VertexProcessor::setFogEnable(bool fogEnable)
357 {
358 context->fogEnable = fogEnable;
359 }
360
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400361 void VertexProcessor::setVertexFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400362 {
363 context->vertexFogMode = fogMode;
364 }
365
Alexis Hetu6743bbf2015-04-21 17:06:14 -0400366 void VertexProcessor::setInstanceID(int instanceID)
367 {
368 context->instanceID = instanceID;
369 }
370
John Bauman89401822014-05-06 15:04:28 -0400371 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
372 {
373 context->setColorVertexEnable(colorVertexEnable);
374 }
375
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400376 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400377 {
378 context->setDiffuseMaterialSource(diffuseMaterialSource);
379 }
380
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400381 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400382 {
383 context->setSpecularMaterialSource(specularMaterialSource);
384 }
385
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400386 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400387 {
388 context->setAmbientMaterialSource(ambientMaterialSource);
389 }
390
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400391 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400392 {
393 context->setEmissiveMaterialSource(emissiveMaterialSource);
394 }
395
396 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
397 {
398 ff.globalAmbient[0] = globalAmbient.r;
399 ff.globalAmbient[1] = globalAmbient.g;
400 ff.globalAmbient[2] = globalAmbient.b;
401 ff.globalAmbient[3] = globalAmbient.a;
402 }
403
404 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
405 {
406 ff.materialEmission[0] = emission.r;
407 ff.materialEmission[1] = emission.g;
408 ff.materialEmission[2] = emission.b;
409 ff.materialEmission[3] = emission.a;
410 }
411
412 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
413 {
414 ff.materialAmbient[0] = materialAmbient.r;
415 ff.materialAmbient[1] = materialAmbient.g;
416 ff.materialAmbient[2] = materialAmbient.b;
417 ff.materialAmbient[3] = materialAmbient.a;
418 }
419
420 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
421 {
422 ff.materialDiffuse[0] = diffuseColor.r;
423 ff.materialDiffuse[1] = diffuseColor.g;
424 ff.materialDiffuse[2] = diffuseColor.b;
425 ff.materialDiffuse[3] = diffuseColor.a;
426 }
427
428 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
429 {
430 ff.materialSpecular[0] = specularColor.r;
431 ff.materialSpecular[1] = specularColor.g;
432 ff.materialSpecular[2] = specularColor.b;
433 ff.materialSpecular[3] = specularColor.a;
434 }
435
436 void VertexProcessor::setMaterialShininess(float specularPower)
437 {
438 ff.materialShininess = specularPower;
439 }
440
441 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
442 {
443 if(light < 8)
444 {
445 ff.lightPosition[light][0] = P.x;
446 ff.lightPosition[light][1] = P.y;
447 ff.lightPosition[light][2] = P.z;
448 ff.lightPosition[light][3] = 1;
449 }
450 else ASSERT(false);
451 }
452
453 void VertexProcessor::setRangeFogEnable(bool enable)
454 {
455 context->rangeFogEnable = enable;
456 }
457
458 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
459 {
460 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
461 }
462
463 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
464 {
465 if(vertexBlendMatrixCount <= 4)
466 {
467 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
468 }
469 else ASSERT(false);
470 }
471
472 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
473 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400474 if(stage < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400475 {
476 context->textureWrap[stage] = mask;
477 }
478 else ASSERT(false);
479
480 context->textureWrapActive = false;
481
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400482 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400483 {
484 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
485 }
486 }
487
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400488 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400489 {
490 if(stage < 8)
491 {
492 context->texGen[stage] = texGen;
493 }
494 else ASSERT(false);
495 }
496
497 void VertexProcessor::setLocalViewer(bool localViewer)
498 {
499 context->localViewer = localViewer;
500 }
501
502 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
503 {
504 context->normalizeNormals = normalizeNormals;
505 }
506
507 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
508 {
509 for(int i = 0; i < 4; i++)
510 {
511 for(int j = 0; j < 4; j++)
512 {
513 ff.textureTransform[stage][i][j] = T[i][j];
514 }
515 }
516 }
517
518 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
519 {
520 context->textureTransformCount[stage] = count;
521 context->textureTransformProject[stage] = project;
522 }
523
524 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
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].setTextureFilter(textureFilter);
John Bauman89401822014-05-06 15:04:28 -0400529 }
530 else ASSERT(false);
531 }
532
533 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
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].setMipmapFilter(mipmapFilter);
John Bauman89401822014-05-06 15:04:28 -0400538 }
539 else ASSERT(false);
540 }
541
542 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
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].setGatherEnable(enable);
John Bauman89401822014-05-06 15:04:28 -0400547 }
548 else ASSERT(false);
549 }
550
551 void VertexProcessor::setAddressingModeU(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].setAddressingModeU(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400556 }
557 else ASSERT(false);
558 }
559
560 void VertexProcessor::setAddressingModeV(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].setAddressingModeV(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400565 }
566 else ASSERT(false);
567 }
568
569 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
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].setAddressingModeW(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400574 }
575 else ASSERT(false);
576 }
577
578 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
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].setReadSRGB(sRGB);
John Bauman89401822014-05-06 15:04:28 -0400583 }
584 else ASSERT(false);
585 }
586
587 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
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].setMipmapLOD(bias);
John Bauman89401822014-05-06 15:04:28 -0400592 }
593 else ASSERT(false);
594 }
595
596 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
597 {
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].setBorderColor(borderColor);
John Bauman89401822014-05-06 15:04:28 -0400601 }
602 else ASSERT(false);
603 }
604
Alexis Hetu617a5d52014-11-13 10:56:20 -0500605 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400606 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400607 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400608 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400609 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
John Bauman89401822014-05-06 15:04:28 -0400610 }
611 else ASSERT(false);
612 }
613
Alexis Hetu010a4642017-07-18 14:33:04 -0400614 void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
615 {
616 if(sampler < TEXTURE_IMAGE_UNITS)
617 {
618 context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
619 }
620 else ASSERT(false);
621 }
622
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400623 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
624 {
625 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
626 {
627 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
628 }
629 else ASSERT(false);
630 }
631
632 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
633 {
634 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
635 {
636 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
637 }
638 else ASSERT(false);
639 }
640
641 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
642 {
643 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
644 {
645 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
646 }
647 else ASSERT(false);
648 }
649
650 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
651 {
652 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
653 {
654 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
655 }
656 else ASSERT(false);
657 }
658
Nicolas Capensf878d502017-11-06 15:29:46 -0500659 void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
660 {
661 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
662 {
663 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
664 }
665 else ASSERT(false);
666 }
667
Alexis Hetu95ac1872016-06-06 13:26:52 -0400668 void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
669 {
670 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
671 {
672 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
673 }
674 else ASSERT(false);
675 }
676
677 void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
678 {
679 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
680 {
681 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
682 }
683 else ASSERT(false);
684 }
685
Alexis Hetu112d81f2016-06-07 12:36:35 -0400686 void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
687 {
688 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
689 {
690 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
691 }
692 else ASSERT(false);
693 }
694
695 void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
696 {
697 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
698 {
699 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
700 }
701 else ASSERT(false);
702 }
703
Alexis Hetu88482c32018-06-05 17:05:17 -0400704 void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
705 {
706 if(sampler < TEXTURE_IMAGE_UNITS)
707 {
708 context->sampler[sampler].setSyncRequired(isSincRequired);
709 }
710 else ASSERT(false);
711 }
712
John Bauman89401822014-05-06 15:04:28 -0400713 void VertexProcessor::setPointSize(float pointSize)
714 {
715 point.pointSize = replicate(pointSize);
716 }
717
718 void VertexProcessor::setPointSizeMin(float pointSizeMin)
719 {
720 point.pointSizeMin = pointSizeMin;
721 }
722
723 void VertexProcessor::setPointSizeMax(float pointSizeMax)
724 {
725 point.pointSizeMax = pointSizeMax;
726 }
727
728 void VertexProcessor::setPointScaleA(float pointScaleA)
729 {
730 point.pointScaleA = pointScaleA;
731 }
732
733 void VertexProcessor::setPointScaleB(float pointScaleB)
734 {
735 point.pointScaleB = pointScaleB;
736 }
737
738 void VertexProcessor::setPointScaleC(float pointScaleC)
739 {
740 point.pointScaleC = pointScaleC;
741 }
742
Alexis Hetu16116cb2016-03-02 15:59:51 -0500743 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
744 {
745 context->transformFeedbackQueryEnabled = enable;
746 }
747
748 void VertexProcessor::enableTransformFeedback(uint64_t enable)
749 {
750 context->transformFeedbackEnabled = enable;
751 }
752
John Bauman89401822014-05-06 15:04:28 -0400753 const Matrix &VertexProcessor::getModelTransform(int i)
754 {
755 updateTransform();
756 return PBVM[i];
757 }
758
759 const Matrix &VertexProcessor::getViewTransform()
760 {
761 updateTransform();
762 return PBV;
763 }
764
765 bool VertexProcessor::isFixedFunction()
766 {
767 return !context->vertexShader;
768 }
769
770 void VertexProcessor::setTransform(const Matrix &M, int i)
771 {
772 ff.transformT[i][0][0] = M[0][0];
773 ff.transformT[i][0][1] = M[1][0];
774 ff.transformT[i][0][2] = M[2][0];
775 ff.transformT[i][0][3] = M[3][0];
776
777 ff.transformT[i][1][0] = M[0][1];
778 ff.transformT[i][1][1] = M[1][1];
779 ff.transformT[i][1][2] = M[2][1];
780 ff.transformT[i][1][3] = M[3][1];
781
782 ff.transformT[i][2][0] = M[0][2];
783 ff.transformT[i][2][1] = M[1][2];
784 ff.transformT[i][2][2] = M[2][2];
785 ff.transformT[i][2][3] = M[3][2];
786
787 ff.transformT[i][3][0] = M[0][3];
788 ff.transformT[i][3][1] = M[1][3];
789 ff.transformT[i][3][2] = M[2][3];
790 ff.transformT[i][3][3] = M[3][3];
791 }
792
793 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
794 {
795 ff.cameraTransformT[i][0][0] = M[0][0];
796 ff.cameraTransformT[i][0][1] = M[1][0];
797 ff.cameraTransformT[i][0][2] = M[2][0];
798 ff.cameraTransformT[i][0][3] = M[3][0];
799
800 ff.cameraTransformT[i][1][0] = M[0][1];
801 ff.cameraTransformT[i][1][1] = M[1][1];
802 ff.cameraTransformT[i][1][2] = M[2][1];
803 ff.cameraTransformT[i][1][3] = M[3][1];
804
805 ff.cameraTransformT[i][2][0] = M[0][2];
806 ff.cameraTransformT[i][2][1] = M[1][2];
807 ff.cameraTransformT[i][2][2] = M[2][2];
808 ff.cameraTransformT[i][2][3] = M[3][2];
809
810 ff.cameraTransformT[i][3][0] = M[0][3];
811 ff.cameraTransformT[i][3][1] = M[1][3];
812 ff.cameraTransformT[i][3][2] = M[2][3];
813 ff.cameraTransformT[i][3][3] = M[3][3];
814 }
815
816 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
817 {
818 ff.normalTransformT[i][0][0] = M[0][0];
819 ff.normalTransformT[i][0][1] = M[1][0];
820 ff.normalTransformT[i][0][2] = M[2][0];
821 ff.normalTransformT[i][0][3] = M[3][0];
822
823 ff.normalTransformT[i][1][0] = M[0][1];
824 ff.normalTransformT[i][1][1] = M[1][1];
825 ff.normalTransformT[i][1][2] = M[2][1];
826 ff.normalTransformT[i][1][3] = M[3][1];
827
828 ff.normalTransformT[i][2][0] = M[0][2];
829 ff.normalTransformT[i][2][1] = M[1][2];
830 ff.normalTransformT[i][2][2] = M[2][2];
831 ff.normalTransformT[i][2][3] = M[3][2];
832
833 ff.normalTransformT[i][3][0] = M[0][3];
834 ff.normalTransformT[i][3][1] = M[1][3];
835 ff.normalTransformT[i][3][2] = M[2][3];
836 ff.normalTransformT[i][3][3] = M[3][3];
837 }
838
839 void VertexProcessor::updateTransform()
840 {
841 if(!updateMatrix) return;
842
843 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
844
845 if(updateProjectionMatrix)
846 {
847 PB = P * B;
848 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500849
John Bauman89401822014-05-06 15:04:28 -0400850 for(int i = 0; i < activeMatrices; i++)
851 {
852 PBVM[i] = PBV * M[i];
853 updateModelMatrix[i] = false;
854 }
855
856 updateProjectionMatrix = false;
857 updateBaseMatrix = false;
858 updateViewMatrix = false;
859 }
860
861 if(updateBaseMatrix)
862 {
863 PB = P * B;
864 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500865
John Bauman89401822014-05-06 15:04:28 -0400866 for(int i = 0; i < activeMatrices; i++)
867 {
868 PBVM[i] = PBV * M[i];
869 updateModelMatrix[i] = false;
870 }
871
872 updateBaseMatrix = false;
873 updateViewMatrix = false;
874 }
875
876 if(updateViewMatrix)
877 {
878 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500879
John Bauman89401822014-05-06 15:04:28 -0400880 for(int i = 0; i < activeMatrices; i++)
881 {
882 PBVM[i] = PBV * M[i];
883 updateModelMatrix[i] = false;
884 }
885
886 updateViewMatrix = false;
887 }
888
889 for(int i = 0; i < activeMatrices; i++)
890 {
891 if(updateModelMatrix[i])
892 {
893 PBVM[i] = PBV * M[i];
894 updateModelMatrix[i] = false;
895 }
896 }
897
898 for(int i = 0; i < activeMatrices; i++)
899 {
900 setTransform(PBVM[i], i);
901 setCameraTransform(B * V * M[i], i);
902 setNormalTransform(~!(B * V * M[i]), i);
903 }
904
905 updateMatrix = false;
906 }
907
908 void VertexProcessor::setRoutineCacheSize(int cacheSize)
909 {
910 delete routineCache;
Alexis Hetuf2878342019-03-12 16:32:04 -0400911 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536));
John Bauman89401822014-05-06 15:04:28 -0400912 }
913
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400914 const VertexProcessor::State VertexProcessor::update(DrawType drawType)
John Bauman89401822014-05-06 15:04:28 -0400915 {
916 if(isFixedFunction())
917 {
918 updateTransform();
919
920 if(updateLighting)
921 {
922 for(int i = 0; i < 8; i++)
923 {
924 if(context->vertexLightActive(i))
925 {
926 // Light position in camera coordinates
927 setLightViewPosition(i, B * V * context->getLightPosition(i));
928 }
929 }
930
931 updateLighting = false;
932 }
933 }
934
935 State state;
936
937 if(context->vertexShader)
938 {
John Bauman19bac1e2014-05-06 15:23:49 -0400939 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400940 }
941 else
942 {
John Bauman19bac1e2014-05-06 15:23:49 -0400943 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400944 }
945
Alexis Hetu53ad4af2017-12-06 14:49:07 -0500946 state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500947 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400948 state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
949 state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500950
John Bauman89401822014-05-06 15:04:28 -0400951 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
952 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
953 state.vertexNormalActive = context->vertexNormalActive();
954 state.normalizeNormals = context->normalizeNormalsActive();
955 state.vertexLightingActive = context->vertexLightingActive();
956 state.diffuseActive = context->diffuseActive();
957 state.specularActive = context->specularActive();
958 state.vertexSpecularActive = context->vertexSpecularActive();
959
960 state.vertexLightActive = context->vertexLightActive(0) << 0 |
961 context->vertexLightActive(1) << 1 |
962 context->vertexLightActive(2) << 2 |
963 context->vertexLightActive(3) << 3 |
964 context->vertexLightActive(4) << 4 |
965 context->vertexLightActive(5) << 5 |
966 context->vertexLightActive(6) << 6 |
967 context->vertexLightActive(7) << 7;
968
969 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
970 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
971 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
972 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
973 state.fogActive = context->fogActive();
974 state.vertexFogMode = context->vertexFogModeActive();
975 state.rangeFogActive = context->rangeFogActive();
976 state.localViewerActive = context->localViewerActive();
977 state.pointSizeActive = context->pointSizeActive();
978 state.pointScaleActive = context->pointScaleActive();
979
980 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400981 state.superSampling = context->getSuperSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400982
Alexis Hetu16116cb2016-03-02 15:59:51 -0500983 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
984 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
985
Alexis Hetua62a0ca2016-04-20 15:29:51 -0400986 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
987 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
988 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
989 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
990
Nicolas Capensf0aef1a2016-05-18 14:44:21 -0400991 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -0400992 {
993 state.input[i].type = context->input[i].type;
994 state.input[i].count = context->input[i].count;
995 state.input[i].normalized = context->input[i].normalized;
Alexis Hetub7508b82016-09-22 15:36:45 -0400996 state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
John Bauman89401822014-05-06 15:04:28 -0400997 }
998
999 if(!context->vertexShader)
1000 {
1001 for(int i = 0; i < 8; i++)
1002 {
1003 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
1004 state.textureState[i].texGenActive = context->texGenActive(i);
1005 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
1006 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
1007 }
1008 }
1009 else
1010 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -04001011 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -04001012 {
1013 if(context->vertexShader->usesSampler(i))
1014 {
Nicolas Capensf878d502017-11-06 15:29:46 -05001015 state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -04001016 }
1017 }
1018 }
1019
1020 if(context->vertexShader) // FIXME: Also when pre-transformed?
1021 {
Nicolas Capensec0936c2016-05-18 12:32:02 -04001022 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
John Bauman89401822014-05-06 15:04:28 -04001023 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -04001024 state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
1025 state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
1026 state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
1027 state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
John Bauman89401822014-05-06 15:04:28 -04001028 }
1029 }
Alexis Hetu53ad4af2017-12-06 14:49:07 -05001030 else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
John Bauman89401822014-05-06 15:04:28 -04001031 {
1032 state.output[Pos].write = 0xF;
1033
1034 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
1035 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001036 state.output[C0].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001037 }
Nicolas Capens2ca19032016-01-15 16:54:13 -05001038
John Bauman89401822014-05-06 15:04:28 -04001039 if(context->specularActive())
1040 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001041 state.output[C1].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001042 }
1043
1044 for(int stage = 0; stage < 8; stage++)
1045 {
John Bauman19bac1e2014-05-06 15:23:49 -04001046 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
1047 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
1048 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
1049 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -04001050 }
1051
1052 if(context->fogActive())
1053 {
1054 state.output[Fog].xWrite = true;
1055 }
1056
1057 if(context->pointSizeActive())
1058 {
1059 state.output[Pts].yWrite = true;
1060 }
1061 }
1062 else
1063 {
1064 state.output[Pos].write = 0xF;
1065
1066 for(int i = 0; i < 2; i++)
1067 {
1068 if(context->input[Color0 + i])
1069 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001070 state.output[C0 + i].write = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001071 }
1072 }
1073
1074 for(int i = 0; i < 8; i++)
1075 {
1076 if(context->input[TexCoord0 + i])
1077 {
1078 state.output[T0 + i].write = 0xF;
1079 }
1080 }
1081
John Bauman66b8ab22014-05-06 15:57:45 -04001082 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -04001083 {
1084 state.output[Pts].yWrite = true;
1085 }
1086 }
1087
Alexis Hetu53ad4af2017-12-06 14:49:07 -05001088 if(context->vertexShaderModel() < 0x0300)
John Bauman89401822014-05-06 15:04:28 -04001089 {
Nicolas Capens995ddea2016-05-17 11:48:56 -04001090 state.output[C0].clamp = 0xF;
1091 state.output[C1].clamp = 0xF;
John Bauman89401822014-05-06 15:04:28 -04001092 state.output[Fog].xClamp = true;
1093 }
1094
1095 state.hash = state.computeHash();
1096
1097 return state;
1098 }
1099
Ben Clayton6897e9b2019-07-16 17:27:27 +01001100 std::shared_ptr<Routine> VertexProcessor::routine(const State &state)
John Bauman89401822014-05-06 15:04:28 -04001101 {
Ben Clayton6897e9b2019-07-16 17:27:27 +01001102 auto routine = routineCache->query(state);
John Bauman89401822014-05-06 15:04:28 -04001103
1104 if(!routine) // Create one
1105 {
Nicolas Capensccd5ecb2017-01-14 12:52:55 -05001106 VertexRoutine *generator = nullptr;
John Bauman89401822014-05-06 15:04:28 -04001107
1108 if(state.fixedFunction)
1109 {
1110 generator = new VertexPipeline(state);
1111 }
1112 else
1113 {
1114 generator = new VertexProgram(state, context->vertexShader);
1115 }
1116
1117 generator->generate();
Chris Forbes878d4b02019-01-21 10:48:35 -08001118 routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001119 delete generator;
1120
1121 routineCache->add(state, routine);
1122 }
1123
1124 return routine;
1125 }
1126}