blob: 01f6f147b940a918985ced1ccba73280ed08179d [file] [log] [blame]
John Bauman89401822014-05-06 15:04:28 -04001// SwiftShader Software Renderer
2//
John Bauman19bac1e2014-05-06 15:23:49 -04003// Copyright(c) 2005-2012 TransGaming Inc.
John Bauman89401822014-05-06 15:04:28 -04004//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#include "VertexProcessor.hpp"
13
John Bauman89401822014-05-06 15:04:28 -040014#include "Math.hpp"
15#include "VertexPipeline.hpp"
16#include "VertexProgram.hpp"
17#include "VertexShader.hpp"
18#include "PixelShader.hpp"
19#include "Constants.hpp"
20#include "Debug.hpp"
21
John Bauman66b8ab22014-05-06 15:57:45 -040022#include <string.h>
John Bauman89401822014-05-06 15:04:28 -040023
24namespace sw
25{
John Bauman66b8ab22014-05-06 15:57:45 -040026 bool precacheVertex = false;
27
John Bauman89401822014-05-06 15:04:28 -040028 void VertexCache::clear()
29 {
30 for(int i = 0; i < 16; i++)
31 {
32 tag[i] = 0x80000000;
33 }
34 }
35
36 unsigned int VertexProcessor::States::computeHash()
37 {
38 unsigned int *state = (unsigned int*)this;
39 unsigned int hash = 0;
40
Nicolas Capens5d961882016-01-01 23:18:14 -050041 for(unsigned int i = 0; i < sizeof(States) / 4; i++)
John Bauman89401822014-05-06 15:04:28 -040042 {
43 hash ^= state[i];
44 }
45
46 return hash;
47 }
48
49 VertexProcessor::State::State()
50 {
51 memset(this, 0, sizeof(State));
52 }
53
54 bool VertexProcessor::State::operator==(const State &state) const
55 {
56 if(hash != state.hash)
57 {
58 return false;
59 }
60
61 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 {
66 clear();
67 }
68
69 void VertexProcessor::TransformFeedbackInfo::clear()
70 {
71 buffer = nullptr;
72 offset = 0;
73 reg = 0;
74 row = 0;
75 col = 0;
76 stride = 0;
77 }
78
John Bauman89401822014-05-06 15:04:28 -040079 VertexProcessor::VertexProcessor(Context *context) : context(context)
80 {
81 for(int i = 0; i < 12; i++)
82 {
83 M[i] = 1;
84 }
85
86 V = 1;
87 B = 1;
88 P = 0;
89 PB = 0;
90 PBV = 0;
Nicolas Capens2ca19032016-01-15 16:54:13 -050091
John Bauman89401822014-05-06 15:04:28 -040092 for(int i = 0; i < 12; i++)
93 {
94 PBVM[i] = 0;
95 }
96
97 setLightingEnable(true);
98 setSpecularEnable(false);
99
100 for(int i = 0; i < 8; i++)
101 {
102 setLightEnable(i, false);
103 setLightPosition(i, 0);
104 }
105
106 updateMatrix = true;
107 updateViewMatrix = true;
108 updateBaseMatrix = true;
109 updateProjectionMatrix = true;
110 updateLighting = true;
111
112 for(int i = 0; i < 12; i++)
113 {
114 updateModelMatrix[i] = true;
115 }
116
117 routineCache = 0;
118 setRoutineCacheSize(1024);
Nicolas Capens3d7be4e2016-02-07 22:47:00 -0500119
120 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
121 {
122 uniformBuffer[i] = nullptr;
123 }
John Bauman89401822014-05-06 15:04:28 -0400124 }
125
126 VertexProcessor::~VertexProcessor()
127 {
128 delete routineCache;
129 routineCache = 0;
130 }
131
132 void VertexProcessor::setInputStream(int index, const Stream &stream)
133 {
134 context->input[index] = stream;
135 }
136
John Bauman89401822014-05-06 15:04:28 -0400137 void VertexProcessor::resetInputStreams(bool preTransformed)
138 {
Nicolas Capens0f250902015-06-25 15:25:29 -0400139 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400140 {
141 context->input[i].defaults();
142 }
143
144 context->preTransformed = preTransformed;
145 }
146
147 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
148 {
Alexis Hetu028f41b2016-01-13 14:40:47 -0500149 if(index < VERTEX_UNIFORM_VECTORS)
John Bauman89401822014-05-06 15:04:28 -0400150 {
151 c[index][0] = value[0];
152 c[index][1] = value[1];
153 c[index][2] = value[2];
154 c[index][3] = value[3];
155 }
156 else ASSERT(false);
157 }
158
159 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
160 {
161 if(index < 16)
162 {
163 i[index][0] = integer[0];
164 i[index][1] = integer[1];
165 i[index][2] = integer[2];
166 i[index][3] = integer[3];
167 }
168 else ASSERT(false);
169 }
170
171 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
172 {
173 if(index < 16)
174 {
175 b[index] = boolean != 0;
176 }
177 else ASSERT(false);
178 }
179
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400180 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
181 {
182 uniformBuffer[index] = buffer;
183 uniformBufferOffset[index] = offset;
184 }
185
186 void VertexProcessor::lockUniformBuffers(byte** u)
187 {
188 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
189 {
190 u[i] = uniformBuffer[i] ? static_cast<byte*>(uniformBuffer[i]->lock(PUBLIC, PRIVATE)) + uniformBufferOffset[i] : nullptr;
191 }
192 }
193
194 void VertexProcessor::unlockUniformBuffers()
195 {
196 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
197 {
198 if(uniformBuffer[i])
199 {
200 uniformBuffer[i]->unlock();
201 uniformBuffer[i] = nullptr;
202 }
203 }
204 }
205
Alexis Hetu772d2492016-04-04 16:14:58 -0400206 void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, size_t stride)
207 {
208 transformFeedbackInfo[index].buffer = buffer;
209 transformFeedbackInfo[index].offset = offset;
210 transformFeedbackInfo[index].reg = reg;
211 transformFeedbackInfo[index].row = row;
212 transformFeedbackInfo[index].col = col;
213 transformFeedbackInfo[index].stride = stride;
214 }
215
216 void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s)
217 {
218 for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
219 {
220 t[i] = transformFeedbackInfo[i].buffer ? static_cast<byte*>(transformFeedbackInfo[i].buffer->lock(PUBLIC, PRIVATE)) + transformFeedbackInfo[i].offset : nullptr;
221 v[i] = transformFeedbackInfo[i].reg;
222 r[i] = transformFeedbackInfo[i].row;
223 c[i] = transformFeedbackInfo[i].col;
224 s[i] = transformFeedbackInfo[i].stride;
225 }
226 }
227
228 void VertexProcessor::unlockTransformFeedbackBuffers()
229 {
230 for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
231 {
232 if(transformFeedbackInfo[i].buffer)
233 {
234 transformFeedbackInfo[i].buffer->unlock();
235 }
236 transformFeedbackInfo[i].clear();
237 }
238 }
239
John Bauman89401822014-05-06 15:04:28 -0400240 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
241 {
242 if(i < 12)
243 {
244 this->M[i] = M;
245
246 updateMatrix = true;
247 updateModelMatrix[i] = true;
248 updateLighting = true;
249 }
250 else ASSERT(false);
251 }
252
253 void VertexProcessor::setViewMatrix(const Matrix &V)
254 {
255 this->V = V;
256
257 updateMatrix = true;
258 updateViewMatrix = true;
259 }
260
261 void VertexProcessor::setBaseMatrix(const Matrix &B)
262 {
263 this->B = B;
264
265 updateMatrix = true;
266 updateBaseMatrix = true;
267 }
268
269 void VertexProcessor::setProjectionMatrix(const Matrix &P)
270 {
271 this->P = P;
272 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
273
274 updateMatrix = true;
275 updateProjectionMatrix = true;
276 }
277
278 void VertexProcessor::setLightingEnable(bool lightingEnable)
279 {
280 context->setLightingEnable(lightingEnable);
281
282 updateLighting = true;
283 }
284
285 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
286 {
287 if(light < 8)
288 {
289 context->setLightEnable(light, lightEnable);
290 }
291 else ASSERT(false);
292
293 updateLighting = true;
294 }
295
296 void VertexProcessor::setSpecularEnable(bool specularEnable)
297 {
298 context->setSpecularEnable(specularEnable);
299
300 updateLighting = true;
301 }
302
303 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
304 {
305 if(light < 8)
306 {
307 context->setLightPosition(light, lightPosition);
308 }
309 else ASSERT(false);
310
311 updateLighting = true;
312 }
313
314 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
315 {
316 if(light < 8)
317 {
318 ff.lightDiffuse[light][0] = lightDiffuse.r;
319 ff.lightDiffuse[light][1] = lightDiffuse.g;
320 ff.lightDiffuse[light][2] = lightDiffuse.b;
321 ff.lightDiffuse[light][3] = lightDiffuse.a;
322 }
323 else ASSERT(false);
324 }
325
326 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
327 {
328 if(light < 8)
329 {
330 ff.lightSpecular[light][0] = lightSpecular.r;
331 ff.lightSpecular[light][1] = lightSpecular.g;
332 ff.lightSpecular[light][2] = lightSpecular.b;
333 ff.lightSpecular[light][3] = lightSpecular.a;
334 }
335 else ASSERT(false);
336 }
337
338 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
339 {
340 if(light < 8)
341 {
342 ff.lightAmbient[light][0] = lightAmbient.r;
343 ff.lightAmbient[light][1] = lightAmbient.g;
344 ff.lightAmbient[light][2] = lightAmbient.b;
345 ff.lightAmbient[light][3] = lightAmbient.a;
346 }
347 else ASSERT(false);
348 }
349
350 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
351 {
352 if(light < 8)
353 {
Nicolas Capens2ca19032016-01-15 16:54:13 -0500354 ff.attenuationConstant[light] = replicate(constant);
John Bauman89401822014-05-06 15:04:28 -0400355 ff.attenuationLinear[light] = replicate(linear);
356 ff.attenuationQuadratic[light] = replicate(quadratic);
357 }
358 else ASSERT(false);
359 }
360
361 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
362 {
363 if(light < 8)
364 {
365 ff.lightRange[light] = lightRange;
366 }
367 else ASSERT(false);
368 }
369
370 void VertexProcessor::setFogEnable(bool fogEnable)
371 {
372 context->fogEnable = fogEnable;
373 }
374
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400375 void VertexProcessor::setVertexFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400376 {
377 context->vertexFogMode = fogMode;
378 }
379
Alexis Hetu6743bbf2015-04-21 17:06:14 -0400380 void VertexProcessor::setInstanceID(int instanceID)
381 {
382 context->instanceID = instanceID;
383 }
384
John Bauman89401822014-05-06 15:04:28 -0400385 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
386 {
387 context->setColorVertexEnable(colorVertexEnable);
388 }
389
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400390 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400391 {
392 context->setDiffuseMaterialSource(diffuseMaterialSource);
393 }
394
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400395 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400396 {
397 context->setSpecularMaterialSource(specularMaterialSource);
398 }
399
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400400 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400401 {
402 context->setAmbientMaterialSource(ambientMaterialSource);
403 }
404
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400405 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400406 {
407 context->setEmissiveMaterialSource(emissiveMaterialSource);
408 }
409
410 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
411 {
412 ff.globalAmbient[0] = globalAmbient.r;
413 ff.globalAmbient[1] = globalAmbient.g;
414 ff.globalAmbient[2] = globalAmbient.b;
415 ff.globalAmbient[3] = globalAmbient.a;
416 }
417
418 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
419 {
420 ff.materialEmission[0] = emission.r;
421 ff.materialEmission[1] = emission.g;
422 ff.materialEmission[2] = emission.b;
423 ff.materialEmission[3] = emission.a;
424 }
425
426 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
427 {
428 ff.materialAmbient[0] = materialAmbient.r;
429 ff.materialAmbient[1] = materialAmbient.g;
430 ff.materialAmbient[2] = materialAmbient.b;
431 ff.materialAmbient[3] = materialAmbient.a;
432 }
433
434 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
435 {
436 ff.materialDiffuse[0] = diffuseColor.r;
437 ff.materialDiffuse[1] = diffuseColor.g;
438 ff.materialDiffuse[2] = diffuseColor.b;
439 ff.materialDiffuse[3] = diffuseColor.a;
440 }
441
442 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
443 {
444 ff.materialSpecular[0] = specularColor.r;
445 ff.materialSpecular[1] = specularColor.g;
446 ff.materialSpecular[2] = specularColor.b;
447 ff.materialSpecular[3] = specularColor.a;
448 }
449
450 void VertexProcessor::setMaterialShininess(float specularPower)
451 {
452 ff.materialShininess = specularPower;
453 }
454
455 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
456 {
457 if(light < 8)
458 {
459 ff.lightPosition[light][0] = P.x;
460 ff.lightPosition[light][1] = P.y;
461 ff.lightPosition[light][2] = P.z;
462 ff.lightPosition[light][3] = 1;
463 }
464 else ASSERT(false);
465 }
466
467 void VertexProcessor::setRangeFogEnable(bool enable)
468 {
469 context->rangeFogEnable = enable;
470 }
471
472 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
473 {
474 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
475 }
476
477 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
478 {
479 if(vertexBlendMatrixCount <= 4)
480 {
481 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
482 }
483 else ASSERT(false);
484 }
485
486 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
487 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400488 if(stage < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400489 {
490 context->textureWrap[stage] = mask;
491 }
492 else ASSERT(false);
493
494 context->textureWrapActive = false;
495
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400496 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400497 {
498 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
499 }
500 }
501
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400502 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400503 {
504 if(stage < 8)
505 {
506 context->texGen[stage] = texGen;
507 }
508 else ASSERT(false);
509 }
510
511 void VertexProcessor::setLocalViewer(bool localViewer)
512 {
513 context->localViewer = localViewer;
514 }
515
516 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
517 {
518 context->normalizeNormals = normalizeNormals;
519 }
520
521 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
522 {
523 for(int i = 0; i < 4; i++)
524 {
525 for(int j = 0; j < 4; j++)
526 {
527 ff.textureTransform[stage][i][j] = T[i][j];
528 }
529 }
530 }
531
532 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
533 {
534 context->textureTransformCount[stage] = count;
535 context->textureTransformProject[stage] = project;
536 }
537
538 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
539 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400540 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400541 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400542 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
John Bauman89401822014-05-06 15:04:28 -0400543 }
544 else ASSERT(false);
545 }
546
547 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
548 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400549 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400550 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400551 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
John Bauman89401822014-05-06 15:04:28 -0400552 }
553 else ASSERT(false);
554 }
555
556 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
557 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400558 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400559 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400560 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
John Bauman89401822014-05-06 15:04:28 -0400561 }
562 else ASSERT(false);
563 }
564
565 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
566 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400567 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400568 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400569 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400570 }
571 else ASSERT(false);
572 }
573
574 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
575 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400576 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400577 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400578 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400579 }
580 else ASSERT(false);
581 }
582
583 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
584 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400585 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400586 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400587 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400588 }
589 else ASSERT(false);
590 }
591
592 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
593 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400594 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400595 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400596 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
John Bauman89401822014-05-06 15:04:28 -0400597 }
598 else ASSERT(false);
599 }
600
601 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
602 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400603 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400604 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400605 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
John Bauman89401822014-05-06 15:04:28 -0400606 }
607 else ASSERT(false);
608 }
609
610 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
611 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400612 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400613 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400614 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
John Bauman89401822014-05-06 15:04:28 -0400615 }
616 else ASSERT(false);
617 }
618
Alexis Hetu617a5d52014-11-13 10:56:20 -0500619 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400620 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400621 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400622 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400623 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
John Bauman89401822014-05-06 15:04:28 -0400624 }
625 else ASSERT(false);
626 }
627
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400628 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
629 {
630 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
631 {
632 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
633 }
634 else ASSERT(false);
635 }
636
637 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
638 {
639 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
640 {
641 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
642 }
643 else ASSERT(false);
644 }
645
646 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
647 {
648 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
649 {
650 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
651 }
652 else ASSERT(false);
653 }
654
655 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
656 {
657 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
658 {
659 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
660 }
661 else ASSERT(false);
662 }
663
John Bauman89401822014-05-06 15:04:28 -0400664 void VertexProcessor::setPointSize(float pointSize)
665 {
666 point.pointSize = replicate(pointSize);
667 }
668
669 void VertexProcessor::setPointSizeMin(float pointSizeMin)
670 {
671 point.pointSizeMin = pointSizeMin;
672 }
673
674 void VertexProcessor::setPointSizeMax(float pointSizeMax)
675 {
676 point.pointSizeMax = pointSizeMax;
677 }
678
679 void VertexProcessor::setPointScaleA(float pointScaleA)
680 {
681 point.pointScaleA = pointScaleA;
682 }
683
684 void VertexProcessor::setPointScaleB(float pointScaleB)
685 {
686 point.pointScaleB = pointScaleB;
687 }
688
689 void VertexProcessor::setPointScaleC(float pointScaleC)
690 {
691 point.pointScaleC = pointScaleC;
692 }
693
Alexis Hetu16116cb2016-03-02 15:59:51 -0500694 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
695 {
696 context->transformFeedbackQueryEnabled = enable;
697 }
698
699 void VertexProcessor::enableTransformFeedback(uint64_t enable)
700 {
701 context->transformFeedbackEnabled = enable;
702 }
703
John Bauman89401822014-05-06 15:04:28 -0400704 const Matrix &VertexProcessor::getModelTransform(int i)
705 {
706 updateTransform();
707 return PBVM[i];
708 }
709
710 const Matrix &VertexProcessor::getViewTransform()
711 {
712 updateTransform();
713 return PBV;
714 }
715
716 bool VertexProcessor::isFixedFunction()
717 {
718 return !context->vertexShader;
719 }
720
721 void VertexProcessor::setTransform(const Matrix &M, int i)
722 {
723 ff.transformT[i][0][0] = M[0][0];
724 ff.transformT[i][0][1] = M[1][0];
725 ff.transformT[i][0][2] = M[2][0];
726 ff.transformT[i][0][3] = M[3][0];
727
728 ff.transformT[i][1][0] = M[0][1];
729 ff.transformT[i][1][1] = M[1][1];
730 ff.transformT[i][1][2] = M[2][1];
731 ff.transformT[i][1][3] = M[3][1];
732
733 ff.transformT[i][2][0] = M[0][2];
734 ff.transformT[i][2][1] = M[1][2];
735 ff.transformT[i][2][2] = M[2][2];
736 ff.transformT[i][2][3] = M[3][2];
737
738 ff.transformT[i][3][0] = M[0][3];
739 ff.transformT[i][3][1] = M[1][3];
740 ff.transformT[i][3][2] = M[2][3];
741 ff.transformT[i][3][3] = M[3][3];
742 }
743
744 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
745 {
746 ff.cameraTransformT[i][0][0] = M[0][0];
747 ff.cameraTransformT[i][0][1] = M[1][0];
748 ff.cameraTransformT[i][0][2] = M[2][0];
749 ff.cameraTransformT[i][0][3] = M[3][0];
750
751 ff.cameraTransformT[i][1][0] = M[0][1];
752 ff.cameraTransformT[i][1][1] = M[1][1];
753 ff.cameraTransformT[i][1][2] = M[2][1];
754 ff.cameraTransformT[i][1][3] = M[3][1];
755
756 ff.cameraTransformT[i][2][0] = M[0][2];
757 ff.cameraTransformT[i][2][1] = M[1][2];
758 ff.cameraTransformT[i][2][2] = M[2][2];
759 ff.cameraTransformT[i][2][3] = M[3][2];
760
761 ff.cameraTransformT[i][3][0] = M[0][3];
762 ff.cameraTransformT[i][3][1] = M[1][3];
763 ff.cameraTransformT[i][3][2] = M[2][3];
764 ff.cameraTransformT[i][3][3] = M[3][3];
765 }
766
767 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
768 {
769 ff.normalTransformT[i][0][0] = M[0][0];
770 ff.normalTransformT[i][0][1] = M[1][0];
771 ff.normalTransformT[i][0][2] = M[2][0];
772 ff.normalTransformT[i][0][3] = M[3][0];
773
774 ff.normalTransformT[i][1][0] = M[0][1];
775 ff.normalTransformT[i][1][1] = M[1][1];
776 ff.normalTransformT[i][1][2] = M[2][1];
777 ff.normalTransformT[i][1][3] = M[3][1];
778
779 ff.normalTransformT[i][2][0] = M[0][2];
780 ff.normalTransformT[i][2][1] = M[1][2];
781 ff.normalTransformT[i][2][2] = M[2][2];
782 ff.normalTransformT[i][2][3] = M[3][2];
783
784 ff.normalTransformT[i][3][0] = M[0][3];
785 ff.normalTransformT[i][3][1] = M[1][3];
786 ff.normalTransformT[i][3][2] = M[2][3];
787 ff.normalTransformT[i][3][3] = M[3][3];
788 }
789
790 void VertexProcessor::updateTransform()
791 {
792 if(!updateMatrix) return;
793
794 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
795
796 if(updateProjectionMatrix)
797 {
798 PB = P * B;
799 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500800
John Bauman89401822014-05-06 15:04:28 -0400801 for(int i = 0; i < activeMatrices; i++)
802 {
803 PBVM[i] = PBV * M[i];
804 updateModelMatrix[i] = false;
805 }
806
807 updateProjectionMatrix = false;
808 updateBaseMatrix = false;
809 updateViewMatrix = false;
810 }
811
812 if(updateBaseMatrix)
813 {
814 PB = P * B;
815 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500816
John Bauman89401822014-05-06 15:04:28 -0400817 for(int i = 0; i < activeMatrices; i++)
818 {
819 PBVM[i] = PBV * M[i];
820 updateModelMatrix[i] = false;
821 }
822
823 updateBaseMatrix = false;
824 updateViewMatrix = false;
825 }
826
827 if(updateViewMatrix)
828 {
829 PBV = PB * V;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500830
John Bauman89401822014-05-06 15:04:28 -0400831 for(int i = 0; i < activeMatrices; i++)
832 {
833 PBVM[i] = PBV * M[i];
834 updateModelMatrix[i] = false;
835 }
836
837 updateViewMatrix = false;
838 }
839
840 for(int i = 0; i < activeMatrices; i++)
841 {
842 if(updateModelMatrix[i])
843 {
844 PBVM[i] = PBV * M[i];
845 updateModelMatrix[i] = false;
846 }
847 }
848
849 for(int i = 0; i < activeMatrices; i++)
850 {
851 setTransform(PBVM[i], i);
852 setCameraTransform(B * V * M[i], i);
853 setNormalTransform(~!(B * V * M[i]), i);
854 }
855
856 updateMatrix = false;
857 }
858
859 void VertexProcessor::setRoutineCacheSize(int cacheSize)
860 {
861 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400862 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400863 }
864
865 const VertexProcessor::State VertexProcessor::update()
866 {
867 if(isFixedFunction())
868 {
869 updateTransform();
870
871 if(updateLighting)
872 {
873 for(int i = 0; i < 8; i++)
874 {
875 if(context->vertexLightActive(i))
876 {
877 // Light position in camera coordinates
878 setLightViewPosition(i, B * V * context->getLightPosition(i));
879 }
880 }
881
882 updateLighting = false;
883 }
884 }
885
886 State state;
887
888 if(context->vertexShader)
889 {
John Bauman19bac1e2014-05-06 15:23:49 -0400890 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400891 }
892 else
893 {
John Bauman19bac1e2014-05-06 15:23:49 -0400894 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400895 }
896
897 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500898 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
John Bauman89401822014-05-06 15:04:28 -0400899 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
900 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
Nicolas Capens2ca19032016-01-15 16:54:13 -0500901
John Bauman89401822014-05-06 15:04:28 -0400902 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
903 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
904 state.vertexNormalActive = context->vertexNormalActive();
905 state.normalizeNormals = context->normalizeNormalsActive();
906 state.vertexLightingActive = context->vertexLightingActive();
907 state.diffuseActive = context->diffuseActive();
908 state.specularActive = context->specularActive();
909 state.vertexSpecularActive = context->vertexSpecularActive();
910
911 state.vertexLightActive = context->vertexLightActive(0) << 0 |
912 context->vertexLightActive(1) << 1 |
913 context->vertexLightActive(2) << 2 |
914 context->vertexLightActive(3) << 3 |
915 context->vertexLightActive(4) << 4 |
916 context->vertexLightActive(5) << 5 |
917 context->vertexLightActive(6) << 6 |
918 context->vertexLightActive(7) << 7;
919
920 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
921 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
922 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
923 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
924 state.fogActive = context->fogActive();
925 state.vertexFogMode = context->vertexFogModeActive();
926 state.rangeFogActive = context->rangeFogActive();
927 state.localViewerActive = context->localViewerActive();
928 state.pointSizeActive = context->pointSizeActive();
929 state.pointScaleActive = context->pointScaleActive();
930
931 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400932 state.superSampling = context->getSuperSampleCount() > 1;
933 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400934
Alexis Hetu16116cb2016-03-02 15:59:51 -0500935 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
936 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
937
Nicolas Capens0f250902015-06-25 15:25:29 -0400938 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400939 {
940 state.input[i].type = context->input[i].type;
941 state.input[i].count = context->input[i].count;
942 state.input[i].normalized = context->input[i].normalized;
943 }
944
945 if(!context->vertexShader)
946 {
947 for(int i = 0; i < 8; i++)
948 {
949 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
950 state.textureState[i].texGenActive = context->texGenActive(i);
951 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
952 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
953 }
954 }
955 else
956 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400957 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400958 {
959 if(context->vertexShader->usesSampler(i))
960 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400961 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400962 }
963 }
964 }
965
966 if(context->vertexShader) // FIXME: Also when pre-transformed?
967 {
968 for(int i = 0; i < 12; i++)
969 {
970 state.output[i].xWrite = context->vertexShader->output[i][0].active();
971 state.output[i].yWrite = context->vertexShader->output[i][1].active();
972 state.output[i].zWrite = context->vertexShader->output[i][2].active();
973 state.output[i].wWrite = context->vertexShader->output[i][3].active();
974 }
975 }
976 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
977 {
978 state.output[Pos].write = 0xF;
979
980 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
981 {
982 state.output[D0].write = 0xF;
983 }
Nicolas Capens2ca19032016-01-15 16:54:13 -0500984
John Bauman89401822014-05-06 15:04:28 -0400985 if(context->specularActive())
986 {
987 state.output[D1].write = 0xF;
988 }
989
990 for(int stage = 0; stage < 8; stage++)
991 {
John Bauman19bac1e2014-05-06 15:23:49 -0400992 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
993 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
994 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
995 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400996 }
997
998 if(context->fogActive())
999 {
1000 state.output[Fog].xWrite = true;
1001 }
1002
1003 if(context->pointSizeActive())
1004 {
1005 state.output[Pts].yWrite = true;
1006 }
1007 }
1008 else
1009 {
1010 state.output[Pos].write = 0xF;
1011
1012 for(int i = 0; i < 2; i++)
1013 {
1014 if(context->input[Color0 + i])
1015 {
1016 state.output[D0 + i].write = 0xF;
1017 }
1018 }
1019
1020 for(int i = 0; i < 8; i++)
1021 {
1022 if(context->input[TexCoord0 + i])
1023 {
1024 state.output[T0 + i].write = 0xF;
1025 }
1026 }
1027
John Bauman66b8ab22014-05-06 15:57:45 -04001028 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -04001029 {
1030 state.output[Pts].yWrite = true;
1031 }
1032 }
1033
1034 if(context->vertexShaderVersion() < 0x0300)
1035 {
1036 state.output[D0].clamp = 0xF;
1037 state.output[D1].clamp = 0xF;
1038 state.output[Fog].xClamp = true;
1039 }
1040
1041 state.hash = state.computeHash();
1042
1043 return state;
1044 }
1045
1046 Routine *VertexProcessor::routine(const State &state)
1047 {
1048 Routine *routine = routineCache->query(state);
1049
1050 if(!routine) // Create one
1051 {
1052 VertexRoutine *generator = 0;
1053
1054 if(state.fixedFunction)
1055 {
1056 generator = new VertexPipeline(state);
1057 }
1058 else
1059 {
1060 generator = new VertexProgram(state, context->vertexShader);
1061 }
1062
1063 generator->generate();
Nicolas Capens2ca19032016-01-15 16:54:13 -05001064 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001065 delete generator;
1066
1067 routineCache->add(state, routine);
1068 }
1069
1070 return routine;
1071 }
1072}