blob: bd6ea30b2ed23005b15b5343bec0087aa4bd207b [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 "PixelProcessor.hpp"
13
14#include "QuadRasterizer.hpp"
15#include "PixelShader.hpp"
16#include "MetaMacro.hpp"
17#include "Surface.hpp"
18#include "Primitive.hpp"
19#include "Constants.hpp"
20#include "Debug.hpp"
21
22namespace sw
23{
24 extern bool complementaryDepthBuffer;
25 extern Context::TransparencyAntialiasing transparencyAntialiasing;
26 extern bool perspectiveCorrection;
27
28 unsigned int PixelProcessor::States::computeHash()
29 {
30 unsigned int *state = (unsigned int*)this;
31 unsigned int hash = 0;
32
33 for(int i = 0; i < sizeof(States) / 4; i++)
34 {
35 hash ^= state[i];
36 }
37
38 return hash;
39 }
40
41 PixelProcessor::State::State()
42 {
43 memset(this, 0, sizeof(State));
44 }
45
46 bool PixelProcessor::State::operator==(const State &state) const
47 {
48 if(hash != state.hash)
49 {
50 return false;
51 }
52
53 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
54 }
55
56 PixelProcessor::PixelProcessor(Context *context) : context(context)
57 {
58 setGlobalMipmapBias(0.0f); // Round to highest LOD [0.5, 1.0]: -0.5
59 // Round to nearest LOD [0.7, 1.4]: 0.0
60 // Round to lowest LOD [1.0, 2.0]: 0.5
61
John Bauman19bac1e2014-05-06 15:23:49 -040062 precacheDLL = 0;
John Bauman89401822014-05-06 15:04:28 -040063 routineCache = 0;
64 setRoutineCacheSize(1024);
65 }
66
67 PixelProcessor::~PixelProcessor()
68 {
69 delete routineCache;
70 routineCache = 0;
71 }
72
73 void PixelProcessor::setFloatConstant(unsigned int index, const float value[4])
74 {
75 if(index < 224)
76 {
77 c[index][0] = value[0];
78 c[index][1] = value[1];
79 c[index][2] = value[2];
80 c[index][3] = value[3];
81 }
82 else ASSERT(false);
83
84 if(index < 8) // ps_1_x constants
85 {
86 // FIXME: Compact into generic function
87 short x = iround(4095 * clamp(value[0], -1.0f, 1.0f));
88 short y = iround(4095 * clamp(value[1], -1.0f, 1.0f));
89 short z = iround(4095 * clamp(value[2], -1.0f, 1.0f));
90 short w = iround(4095 * clamp(value[3], -1.0f, 1.0f));
91
92 cW[index][0][0] = x;
93 cW[index][0][1] = x;
94 cW[index][0][2] = x;
95 cW[index][0][3] = x;
96
97 cW[index][1][0] = y;
98 cW[index][1][1] = y;
99 cW[index][1][2] = y;
100 cW[index][1][3] = y;
101
102 cW[index][2][0] = z;
103 cW[index][2][1] = z;
104 cW[index][2][2] = z;
105 cW[index][2][3] = z;
106
107 cW[index][3][0] = w;
108 cW[index][3][1] = w;
109 cW[index][3][2] = w;
110 cW[index][3][3] = w;
111 }
112 }
113
114 void PixelProcessor::setIntegerConstant(unsigned int index, const int value[4])
115 {
116 if(index < 16)
117 {
118 i[index][0] = value[0];
119 i[index][1] = value[1];
120 i[index][2] = value[2];
121 i[index][3] = value[3];
122 }
123 else ASSERT(false);
124 }
125
126 void PixelProcessor::setBooleanConstant(unsigned int index, int boolean)
127 {
128 if(index < 16)
129 {
130 b[index] = boolean != 0;
131 }
132 else ASSERT(false);
133 }
134
135 void PixelProcessor::setRenderTarget(int index, Surface *renderTarget)
136 {
137 context->renderTarget[index] = renderTarget;
138 }
139
140 void PixelProcessor::setDepthStencil(Surface *depthStencil)
141 {
142 context->depthStencil = depthStencil;
143 }
144
145 void PixelProcessor::setTexCoordIndex(unsigned int stage, int texCoordIndex)
146 {
147 if(stage < 8)
148 {
149 context->textureStage[stage].setTexCoordIndex(texCoordIndex);
150 }
151 else ASSERT(false);
152 }
153
154 void PixelProcessor::setStageOperation(unsigned int stage, TextureStage::StageOperation stageOperation)
155 {
156 if(stage < 8)
157 {
158 context->textureStage[stage].setStageOperation(stageOperation);
159 }
160 else ASSERT(false);
161 }
162
163 void PixelProcessor::setFirstArgument(unsigned int stage, TextureStage::SourceArgument firstArgument)
164 {
165 if(stage < 8)
166 {
167 context->textureStage[stage].setFirstArgument(firstArgument);
168 }
169 else ASSERT(false);
170 }
171
172 void PixelProcessor::setSecondArgument(unsigned int stage, TextureStage::SourceArgument secondArgument)
173 {
174 if(stage < 8)
175 {
176 context->textureStage[stage].setSecondArgument(secondArgument);
177 }
178 else ASSERT(false);
179 }
180
181 void PixelProcessor::setThirdArgument(unsigned int stage, TextureStage::SourceArgument thirdArgument)
182 {
183 if(stage < 8)
184 {
185 context->textureStage[stage].setThirdArgument(thirdArgument);
186 }
187 else ASSERT(false);
188 }
189
190 void PixelProcessor::setStageOperationAlpha(unsigned int stage, TextureStage::StageOperation stageOperationAlpha)
191 {
192 if(stage < 8)
193 {
194 context->textureStage[stage].setStageOperationAlpha(stageOperationAlpha);
195 }
196 else ASSERT(false);
197 }
198
199 void PixelProcessor::setFirstArgumentAlpha(unsigned int stage, TextureStage::SourceArgument firstArgumentAlpha)
200 {
201 if(stage < 8)
202 {
203 context->textureStage[stage].setFirstArgumentAlpha(firstArgumentAlpha);
204 }
205 else ASSERT(false);
206 }
207
208 void PixelProcessor::setSecondArgumentAlpha(unsigned int stage, TextureStage::SourceArgument secondArgumentAlpha)
209 {
210 if(stage < 8)
211 {
212 context->textureStage[stage].setSecondArgumentAlpha(secondArgumentAlpha);
213 }
214 else ASSERT(false);
215 }
216
217 void PixelProcessor::setThirdArgumentAlpha(unsigned int stage, TextureStage::SourceArgument thirdArgumentAlpha)
218 {
219 if(stage < 8)
220 {
221 context->textureStage[stage].setThirdArgumentAlpha(thirdArgumentAlpha);
222 }
223 else ASSERT(false);
224 }
225
226 void PixelProcessor::setFirstModifier(unsigned int stage, TextureStage::ArgumentModifier firstModifier)
227 {
228 if(stage < 8)
229 {
230 context->textureStage[stage].setFirstModifier(firstModifier);
231 }
232 else ASSERT(false);
233 }
234
235 void PixelProcessor::setSecondModifier(unsigned int stage, TextureStage::ArgumentModifier secondModifier)
236 {
237 if(stage < 8)
238 {
239 context->textureStage[stage].setSecondModifier(secondModifier);
240 }
241 else ASSERT(false);
242 }
243
244 void PixelProcessor::setThirdModifier(unsigned int stage, TextureStage::ArgumentModifier thirdModifier)
245 {
246 if(stage < 8)
247 {
248 context->textureStage[stage].setThirdModifier(thirdModifier);
249 }
250 else ASSERT(false);
251 }
252
253 void PixelProcessor::setFirstModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier firstModifierAlpha)
254 {
255 if(stage < 8)
256 {
257 context->textureStage[stage].setFirstModifierAlpha(firstModifierAlpha);
258 }
259 else ASSERT(false);
260 }
261
262 void PixelProcessor::setSecondModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier secondModifierAlpha)
263 {
264 if(stage < 8)
265 {
266 context->textureStage[stage].setSecondModifierAlpha(secondModifierAlpha);
267 }
268 else ASSERT(false);
269 }
270
271 void PixelProcessor::setThirdModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier thirdModifierAlpha)
272 {
273 if(stage < 8)
274 {
275 context->textureStage[stage].setThirdModifierAlpha(thirdModifierAlpha);
276 }
277 else ASSERT(false);
278 }
279
280 void PixelProcessor::setDestinationArgument(unsigned int stage, TextureStage::DestinationArgument destinationArgument)
281 {
282 if(stage < 8)
283 {
284 context->textureStage[stage].setDestinationArgument(destinationArgument);
285 }
286 else ASSERT(false);
287 }
288
289 void PixelProcessor::setConstantColor(unsigned int stage, const Color<float> &constantColor)
290 {
291 if(stage < 8)
292 {
293 context->textureStage[stage].setConstantColor(constantColor);
294 }
295 else ASSERT(false);
296 }
297
298 void PixelProcessor::setBumpmapMatrix(unsigned int stage, int element, float value)
299 {
300 if(stage < 8)
301 {
302 context->textureStage[stage].setBumpmapMatrix(element, value);
303 }
304 else ASSERT(false);
305 }
306
307 void PixelProcessor::setLuminanceScale(unsigned int stage, float value)
308 {
309 if(stage < 8)
310 {
311 context->textureStage[stage].setLuminanceScale(value);
312 }
313 else ASSERT(false);
314 }
315
316 void PixelProcessor::setLuminanceOffset(unsigned int stage, float value)
317 {
318 if(stage < 8)
319 {
320 context->textureStage[stage].setLuminanceOffset(value);
321 }
322 else ASSERT(false);
323 }
324
325 void PixelProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
326 {
327 if(sampler < 16)
328 {
329 context->sampler[sampler].setTextureFilter(textureFilter);
330 }
331 else ASSERT(false);
332 }
333
334 void PixelProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
335 {
336 if(sampler < 16)
337 {
338 context->sampler[sampler].setMipmapFilter(mipmapFilter);
339 }
340 else ASSERT(false);
341 }
342
343 void PixelProcessor::setGatherEnable(unsigned int sampler, bool enable)
344 {
345 if(sampler < 16)
346 {
347 context->sampler[sampler].setGatherEnable(enable);
348 }
349 else ASSERT(false);
350 }
351
352 void PixelProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
353 {
354 if(sampler < 16)
355 {
356 context->sampler[sampler].setAddressingModeU(addressMode);
357 }
358 else ASSERT(false);
359 }
360
361 void PixelProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
362 {
363 if(sampler < 16)
364 {
365 context->sampler[sampler].setAddressingModeV(addressMode);
366 }
367 else ASSERT(false);
368 }
369
370 void PixelProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
371 {
372 if(sampler < 16)
373 {
374 context->sampler[sampler].setAddressingModeW(addressMode);
375 }
376 else ASSERT(false);
377 }
378
379 void PixelProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
380 {
381 if(sampler < 16)
382 {
383 context->sampler[sampler].setReadSRGB(sRGB);
384 }
385 else ASSERT(false);
386 }
387
388 void PixelProcessor::setMipmapLOD(unsigned int sampler, float bias)
389 {
390 if(sampler < 16)
391 {
392 context->sampler[sampler].setMipmapLOD(bias);
393 }
394 else ASSERT(false);
395 }
396
397 void PixelProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
398 {
399 if(sampler < 16)
400 {
401 context->sampler[sampler].setBorderColor(borderColor);
402 }
403 else ASSERT(false);
404 }
405
406 void PixelProcessor::setMaxAnisotropy(unsigned int sampler, unsigned int maxAnisotropy)
407 {
408 if(sampler < 16)
409 {
410 context->sampler[sampler].setMaxAnisotropy(maxAnisotropy);
411 }
412 else ASSERT(false);
413 }
414
415 void PixelProcessor::setWriteSRGB(bool sRGB)
416 {
417 context->setWriteSRGB(sRGB);
418 }
419
420 void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable)
421 {
422 context->setDepthBufferEnable(depthBufferEnable);
423 }
424
425 void PixelProcessor::setDepthCompare(Context::DepthCompareMode depthCompareMode)
426 {
427 context->depthCompareMode = depthCompareMode;
428 }
429
430 void PixelProcessor::setAlphaCompare(Context::AlphaCompareMode alphaCompareMode)
431 {
432 context->alphaCompareMode = alphaCompareMode;
433 }
434
435 void PixelProcessor::setDepthWriteEnable(bool depthWriteEnable)
436 {
437 context->depthWriteEnable = depthWriteEnable;
438 }
439
440 void PixelProcessor::setAlphaTestEnable(bool alphaTestEnable)
441 {
442 context->alphaTestEnable = alphaTestEnable;
443 }
444
445 void PixelProcessor::setCullMode(Context::CullMode cullMode)
446 {
447 context->cullMode = cullMode;
448 }
449
450 void PixelProcessor::setColorWriteMask(int index, int rgbaMask)
451 {
452 context->setColorWriteMask(index, rgbaMask);
453 }
454
455 void PixelProcessor::setStencilEnable(bool stencilEnable)
456 {
457 context->stencilEnable = stencilEnable;
458 }
459
460 void PixelProcessor::setStencilCompare(Context::StencilCompareMode stencilCompareMode)
461 {
462 context->stencilCompareMode = stencilCompareMode;
463 }
464
465 void PixelProcessor::setStencilReference(int stencilReference)
466 {
467 context->stencilReference = stencilReference;
468 stencil.set(stencilReference, context->stencilMask, context->stencilWriteMask);
469 }
470
471 void PixelProcessor::setStencilReferenceCCW(int stencilReferenceCCW)
472 {
473 context->stencilReferenceCCW = stencilReferenceCCW;
474 stencilCCW.set(stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW);
475 }
476
477 void PixelProcessor::setStencilMask(int stencilMask)
478 {
479 context->stencilMask = stencilMask;
480 stencil.set(context->stencilReference, stencilMask, context->stencilWriteMask);
481 }
482
483 void PixelProcessor::setStencilMaskCCW(int stencilMaskCCW)
484 {
485 context->stencilMaskCCW = stencilMaskCCW;
486 stencilCCW.set(context->stencilReferenceCCW, stencilMaskCCW, context->stencilWriteMaskCCW);
487 }
488
489 void PixelProcessor::setStencilFailOperation(Context::StencilOperation stencilFailOperation)
490 {
491 context->stencilFailOperation = stencilFailOperation;
492 }
493
494 void PixelProcessor::setStencilPassOperation(Context::StencilOperation stencilPassOperation)
495 {
496 context->stencilPassOperation = stencilPassOperation;
497 }
498
499 void PixelProcessor::setStencilZFailOperation(Context::StencilOperation stencilZFailOperation)
500 {
501 context->stencilZFailOperation = stencilZFailOperation;
502 }
503
504 void PixelProcessor::setStencilWriteMask(int stencilWriteMask)
505 {
506 context->stencilWriteMask = stencilWriteMask;
507 stencil.set(context->stencilReference, context->stencilMask, stencilWriteMask);
508 }
509
510 void PixelProcessor::setStencilWriteMaskCCW(int stencilWriteMaskCCW)
511 {
512 context->stencilWriteMaskCCW = stencilWriteMaskCCW;
513 stencilCCW.set(context->stencilReferenceCCW, context->stencilMaskCCW, stencilWriteMaskCCW);
514 }
515
516 void PixelProcessor::setTwoSidedStencil(bool enable)
517 {
518 context->twoSidedStencil = enable;
519 }
520
521 void PixelProcessor::setStencilCompareCCW(Context::StencilCompareMode stencilCompareMode)
522 {
523 context->stencilCompareModeCCW = stencilCompareMode;
524 }
525
526 void PixelProcessor::setStencilFailOperationCCW(Context::StencilOperation stencilFailOperation)
527 {
528 context->stencilFailOperationCCW = stencilFailOperation;
529 }
530
531 void PixelProcessor::setStencilPassOperationCCW(Context::StencilOperation stencilPassOperation)
532 {
533 context->stencilPassOperationCCW = stencilPassOperation;
534 }
535
536 void PixelProcessor::setStencilZFailOperationCCW(Context::StencilOperation stencilZFailOperation)
537 {
538 context->stencilZFailOperationCCW = stencilZFailOperation;
539 }
540
541 void PixelProcessor::setTextureFactor(const Color<float> &textureFactor)
542 {
543 // FIXME: Compact into generic function // FIXME: Clamp
544 short textureFactorR = iround(4095 * textureFactor.r);
545 short textureFactorG = iround(4095 * textureFactor.g);
546 short textureFactorB = iround(4095 * textureFactor.b);
547 short textureFactorA = iround(4095 * textureFactor.a);
548
549 factor.textureFactor4[0][0] = textureFactorR;
550 factor.textureFactor4[0][1] = textureFactorR;
551 factor.textureFactor4[0][2] = textureFactorR;
552 factor.textureFactor4[0][3] = textureFactorR;
553
554 factor.textureFactor4[1][0] = textureFactorG;
555 factor.textureFactor4[1][1] = textureFactorG;
556 factor.textureFactor4[1][2] = textureFactorG;
557 factor.textureFactor4[1][3] = textureFactorG;
558
559 factor.textureFactor4[2][0] = textureFactorB;
560 factor.textureFactor4[2][1] = textureFactorB;
561 factor.textureFactor4[2][2] = textureFactorB;
562 factor.textureFactor4[2][3] = textureFactorB;
563
564 factor.textureFactor4[3][0] = textureFactorA;
565 factor.textureFactor4[3][1] = textureFactorA;
566 factor.textureFactor4[3][2] = textureFactorA;
567 factor.textureFactor4[3][3] = textureFactorA;
568 }
569
570 void PixelProcessor::setBlendConstant(const Color<float> &blendConstant)
571 {
572 // FIXME: Compact into generic function // FIXME: Clamp
573 short blendConstantR = iround(65535 * blendConstant.r);
574 short blendConstantG = iround(65535 * blendConstant.g);
575 short blendConstantB = iround(65535 * blendConstant.b);
576 short blendConstantA = iround(65535 * blendConstant.a);
577
578 factor.blendConstant4W[0][0] = blendConstantR;
579 factor.blendConstant4W[0][1] = blendConstantR;
580 factor.blendConstant4W[0][2] = blendConstantR;
581 factor.blendConstant4W[0][3] = blendConstantR;
582
583 factor.blendConstant4W[1][0] = blendConstantG;
584 factor.blendConstant4W[1][1] = blendConstantG;
585 factor.blendConstant4W[1][2] = blendConstantG;
586 factor.blendConstant4W[1][3] = blendConstantG;
587
588 factor.blendConstant4W[2][0] = blendConstantB;
589 factor.blendConstant4W[2][1] = blendConstantB;
590 factor.blendConstant4W[2][2] = blendConstantB;
591 factor.blendConstant4W[2][3] = blendConstantB;
592
593 factor.blendConstant4W[3][0] = blendConstantA;
594 factor.blendConstant4W[3][1] = blendConstantA;
595 factor.blendConstant4W[3][2] = blendConstantA;
596 factor.blendConstant4W[3][3] = blendConstantA;
597
598 // FIXME: Compact into generic function // FIXME: Clamp
599 short invBlendConstantR = iround(65535 * (1 - blendConstant.r));
600 short invBlendConstantG = iround(65535 * (1 - blendConstant.g));
601 short invBlendConstantB = iround(65535 * (1 - blendConstant.b));
602 short invBlendConstantA = iround(65535 * (1 - blendConstant.a));
603
604 factor.invBlendConstant4W[0][0] = invBlendConstantR;
605 factor.invBlendConstant4W[0][1] = invBlendConstantR;
606 factor.invBlendConstant4W[0][2] = invBlendConstantR;
607 factor.invBlendConstant4W[0][3] = invBlendConstantR;
608
609 factor.invBlendConstant4W[1][0] = invBlendConstantG;
610 factor.invBlendConstant4W[1][1] = invBlendConstantG;
611 factor.invBlendConstant4W[1][2] = invBlendConstantG;
612 factor.invBlendConstant4W[1][3] = invBlendConstantG;
613
614 factor.invBlendConstant4W[2][0] = invBlendConstantB;
615 factor.invBlendConstant4W[2][1] = invBlendConstantB;
616 factor.invBlendConstant4W[2][2] = invBlendConstantB;
617 factor.invBlendConstant4W[2][3] = invBlendConstantB;
618
619 factor.invBlendConstant4W[3][0] = invBlendConstantA;
620 factor.invBlendConstant4W[3][1] = invBlendConstantA;
621 factor.invBlendConstant4W[3][2] = invBlendConstantA;
622 factor.invBlendConstant4W[3][3] = invBlendConstantA;
623
624 factor.blendConstant4F[0][0] = blendConstant.r;
625 factor.blendConstant4F[0][1] = blendConstant.r;
626 factor.blendConstant4F[0][2] = blendConstant.r;
627 factor.blendConstant4F[0][3] = blendConstant.r;
628
629 factor.blendConstant4F[1][0] = blendConstant.g;
630 factor.blendConstant4F[1][1] = blendConstant.g;
631 factor.blendConstant4F[1][2] = blendConstant.g;
632 factor.blendConstant4F[1][3] = blendConstant.g;
633
634 factor.blendConstant4F[2][0] = blendConstant.b;
635 factor.blendConstant4F[2][1] = blendConstant.b;
636 factor.blendConstant4F[2][2] = blendConstant.b;
637 factor.blendConstant4F[2][3] = blendConstant.b;
638
639 factor.blendConstant4F[3][0] = blendConstant.a;
640 factor.blendConstant4F[3][1] = blendConstant.a;
641 factor.blendConstant4F[3][2] = blendConstant.a;
642 factor.blendConstant4F[3][3] = blendConstant.a;
643
644 factor.invBlendConstant4F[0][0] = 1 - blendConstant.r;
645 factor.invBlendConstant4F[0][1] = 1 - blendConstant.r;
646 factor.invBlendConstant4F[0][2] = 1 - blendConstant.r;
647 factor.invBlendConstant4F[0][3] = 1 - blendConstant.r;
648
649 factor.invBlendConstant4F[1][0] = 1 - blendConstant.g;
650 factor.invBlendConstant4F[1][1] = 1 - blendConstant.g;
651 factor.invBlendConstant4F[1][2] = 1 - blendConstant.g;
652 factor.invBlendConstant4F[1][3] = 1 - blendConstant.g;
653
654 factor.invBlendConstant4F[2][0] = 1 - blendConstant.b;
655 factor.invBlendConstant4F[2][1] = 1 - blendConstant.b;
656 factor.invBlendConstant4F[2][2] = 1 - blendConstant.b;
657 factor.invBlendConstant4F[2][3] = 1 - blendConstant.b;
658
659 factor.invBlendConstant4F[3][0] = 1 - blendConstant.a;
660 factor.invBlendConstant4F[3][1] = 1 - blendConstant.a;
661 factor.invBlendConstant4F[3][2] = 1 - blendConstant.a;
662 factor.invBlendConstant4F[3][3] = 1 - blendConstant.a;
663 }
664
665 void PixelProcessor::setFillMode(Context::FillMode fillMode)
666 {
667 context->fillMode = fillMode;
668 }
669
670 void PixelProcessor::setShadingMode(Context::ShadingMode shadingMode)
671 {
672 context->shadingMode = shadingMode;
673 }
674
675 void PixelProcessor::setAlphaBlendEnable(bool alphaBlendEnable)
676 {
677 context->setAlphaBlendEnable(alphaBlendEnable);
678 }
679
680 void PixelProcessor::setSourceBlendFactor(Context::BlendFactor sourceBlendFactor)
681 {
682 context->setSourceBlendFactor(sourceBlendFactor);
683 }
684
685 void PixelProcessor::setDestBlendFactor(Context::BlendFactor destBlendFactor)
686 {
687 context->setDestBlendFactor(destBlendFactor);
688 }
689
690 void PixelProcessor::setBlendOperation(Context::BlendOperation blendOperation)
691 {
692 context->setBlendOperation(blendOperation);
693 }
694
695 void PixelProcessor::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)
696 {
697 context->setSeparateAlphaBlendEnable(separateAlphaBlendEnable);
698 }
699
700 void PixelProcessor::setSourceBlendFactorAlpha(Context::BlendFactor sourceBlendFactorAlpha)
701 {
702 context->setSourceBlendFactorAlpha(sourceBlendFactorAlpha);
703 }
704
705 void PixelProcessor::setDestBlendFactorAlpha(Context::BlendFactor destBlendFactorAlpha)
706 {
707 context->setDestBlendFactorAlpha(destBlendFactorAlpha);
708 }
709
710 void PixelProcessor::setBlendOperationAlpha(Context::BlendOperation blendOperationAlpha)
711 {
712 context->setBlendOperationAlpha(blendOperationAlpha);
713 }
714
715 void PixelProcessor::setAlphaReference(int alphaReference)
716 {
717 context->alphaReference = alphaReference;
718
719 factor.alphaReference4[0] = (word)iround((float)alphaReference * 0x1000 / 0xFF);
720 factor.alphaReference4[1] = (word)iround((float)alphaReference * 0x1000 / 0xFF);
721 factor.alphaReference4[2] = (word)iround((float)alphaReference * 0x1000 / 0xFF);
722 factor.alphaReference4[3] = (word)iround((float)alphaReference * 0x1000 / 0xFF);
723 }
724
725 void PixelProcessor::setGlobalMipmapBias(float bias)
726 {
727 context->setGlobalMipmapBias(bias);
728 }
729
730 void PixelProcessor::setFogStart(float start)
731 {
732 setFogRanges(start, context->fogEnd);
733 }
734
735 void PixelProcessor::setFogEnd(float end)
736 {
737 setFogRanges(context->fogStart, end);
738 }
739
740 void PixelProcessor::setFogColor(Color<float> fogColor)
741 {
742 // TODO: Compact into generic function
743 word fogR = (unsigned short)(65535 * fogColor.r);
744 word fogG = (unsigned short)(65535 * fogColor.g);
745 word fogB = (unsigned short)(65535 * fogColor.b);
746
747 fog.color4[0][0] = fogR;
748 fog.color4[0][1] = fogR;
749 fog.color4[0][2] = fogR;
750 fog.color4[0][3] = fogR;
751
752 fog.color4[1][0] = fogG;
753 fog.color4[1][1] = fogG;
754 fog.color4[1][2] = fogG;
755 fog.color4[1][3] = fogG;
756
757 fog.color4[2][0] = fogB;
758 fog.color4[2][1] = fogB;
759 fog.color4[2][2] = fogB;
760 fog.color4[2][3] = fogB;
761
762 fog.colorF[0] = replicate(fogColor.r);
763 fog.colorF[1] = replicate(fogColor.g);
764 fog.colorF[2] = replicate(fogColor.b);
765 }
766
767 void PixelProcessor::setFogDensity(float fogDensity)
768 {
769 fog.densityE = replicate(-fogDensity * 1.442695f); // 1/e^x = 2^(-x*1.44)
770 fog.densityE2 = replicate(fogDensity * 1.201122f); // 1/e^(x^2) = 2^(-(x*1.20)^2)
771 }
772
773 void PixelProcessor::setPixelFogMode(Context::FogMode fogMode)
774 {
775 context->pixelFogMode = fogMode;
776 }
777
778 void PixelProcessor::setPerspectiveCorrection(bool perspectiveEnable)
779 {
780 perspectiveCorrection = perspectiveEnable;
781 }
782
783 void PixelProcessor::setOcclusionEnabled(bool enable)
784 {
785 context->occlusionEnabled = enable;
786 }
787
788 void PixelProcessor::setRoutineCacheSize(int cacheSize)
789 {
790 delete routineCache;
791 routineCache = new LRUCache<State, Routine>(clamp(cacheSize, 1, 65536));
792 }
793
794 void PixelProcessor::setFogRanges(float start, float end)
795 {
796 context->fogStart = start;
797 context->fogEnd = end;
798
799 if(start == end)
800 {
801 end += 0.001f; // Hack: ensure there is a small range
802 }
803
804 float fogScale = -1.0f / (end - start);
805 float fogOffset = end * -fogScale;
806
807 fog.scale = replicate(fogScale);
808 fog.offset = replicate(fogOffset);
809 }
810
811 const PixelProcessor::State PixelProcessor::update() const
812 {
813 State state;
814
815 if(context->pixelShader)
816 {
John Bauman19bac1e2014-05-06 15:23:49 -0400817 state.shaderID = context->pixelShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400818 }
819 else
820 {
John Bauman19bac1e2014-05-06 15:23:49 -0400821 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400822 }
823
824 state.depthOverride = context->pixelShader && context->pixelShader->depthOverride();
John Bauman19bac1e2014-05-06 15:23:49 -0400825 state.shaderContainsKill = context->pixelShader ? context->pixelShader->containsKill() : false;
John Bauman89401822014-05-06 15:04:28 -0400826
827 if(context->alphaTestActive())
828 {
829 state.alphaCompareMode = context->alphaCompareMode;
830
831 state.transparencyAntialiasing = context->renderTarget[0]->getMultiSampleCount() > 1 ? transparencyAntialiasing : Context::TRANSPARENCY_NONE;
832 }
833
834 state.depthWriteEnable = context->depthWriteActive();
835
836 if(context->stencilActive())
837 {
838 state.stencilActive = true;
839 state.stencilCompareMode = context->stencilCompareMode;
840 state.stencilFailOperation = context->stencilFailOperation;
841 state.stencilPassOperation = context->stencilPassOperation;
842 state.stencilZFailOperation = context->stencilZFailOperation;
843 state.noStencilMask = (context->stencilMask == 0xFF);
844 state.noStencilWriteMask = (context->stencilWriteMask == 0xFF);
845 state.stencilWriteMasked = (context->stencilWriteMask == 0x00);
846
847 state.twoSidedStencil = context->twoSidedStencil;
848 state.stencilCompareModeCCW = context->twoSidedStencil ? context->stencilCompareModeCCW : state.stencilCompareMode;
849 state.stencilFailOperationCCW = context->twoSidedStencil ? context->stencilFailOperationCCW : state.stencilFailOperation;
850 state.stencilPassOperationCCW = context->twoSidedStencil ? context->stencilPassOperationCCW : state.stencilPassOperation;
851 state.stencilZFailOperationCCW = context->twoSidedStencil ? context->stencilZFailOperationCCW : state.stencilZFailOperation;
852 state.noStencilMaskCCW = context->twoSidedStencil ? (context->stencilMaskCCW == 0xFF) : state.noStencilMask;
853 state.noStencilWriteMaskCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0xFF) : state.noStencilWriteMask;
854 state.stencilWriteMaskedCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0x00) : state.stencilWriteMasked;
855 }
856
857 if(context->depthBufferActive())
858 {
859 state.depthTestActive = true;
860 state.depthCompareMode = context->depthCompareMode;
861 state.quadLayoutDepthBuffer = context->depthStencil->getInternalFormat() != FORMAT_D32F_LOCKABLE &&
862 context->depthStencil->getInternalFormat() != FORMAT_D32F_TEXTURE &&
863 context->depthStencil->getInternalFormat() != FORMAT_D32F_SHADOW;
864 }
865
866 state.occlusionEnabled = context->occlusionEnabled;
867
868 state.fogActive = context->fogActive();
869 state.pixelFogMode = context->pixelFogActive();
870 state.wBasedFog = context->wBasedFog && context->pixelFogActive() != Context::FOG_NONE;
871 state.perspective = context->perspectiveActive();
872
873 if(context->alphaBlendActive())
874 {
875 state.alphaBlendActive = true;
876 state.sourceBlendFactor = context->sourceBlendFactor();
877 state.destBlendFactor = context->destBlendFactor();
878 state.blendOperation = context->blendOperation();
879 state.sourceBlendFactorAlpha = context->sourceBlendFactorAlpha();
880 state.destBlendFactorAlpha = context->destBlendFactorAlpha();
881 state.blendOperationAlpha = context->blendOperationAlpha();
882 }
883
884 state.colorWriteMask = (context->colorWriteActive(0) << 0) |
885 (context->colorWriteActive(1) << 4) |
886 (context->colorWriteActive(2) << 8) |
887 (context->colorWriteActive(3) << 12);
888
889 for(int i = 0; i < 4; i++)
890 {
891 state.targetFormat[i] = context->renderTargetInternalFormat(i);
892 }
893
894 state.writeSRGB = context->writeSRGB && Surface::isSRGBwritable(context->renderTarget[0]->getExternalFormat());
895 state.multiSample = context->renderTarget[0]->getMultiSampleCount();
896 state.multiSampleMask = context->multiSampleMask;
897
898 if(state.multiSample > 1 && context->pixelShader)
899 {
900 state.centroid = context->pixelShader->containsCentroid();
901 }
902
903 if(!context->pixelShader)
904 {
905 for(unsigned int i = 0; i < 8; i++)
906 {
907 state.textureStage[i] = context->textureStage[i].textureStageState();
908 }
909
910 state.specularAdd = context->specularActive() && context->specularEnable;
911 }
912
913 for(unsigned int i = 0; i < 16; i++)
914 {
915 if(context->pixelShader)
916 {
917 if(context->pixelShader->usesSampler(i))
918 {
919 state.sampler[i] = context->sampler[i].samplerState();
920 }
921 }
922 else
923 {
924 if(i < 8 && state.textureStage[i].stageOperation != TextureStage::STAGE_DISABLE)
925 {
926 state.sampler[i] = context->sampler[i].samplerState();
927 }
928 else break;
929 }
930 }
931
932 const bool point = context->isDrawPoint(true);
933 const bool sprite = context->pointSpriteActive();
934 const bool flatShading = (context->shadingMode == Context::SHADING_FLAT) || point;
935
936 if(context->pixelShaderVersion() < 0x0300)
937 {
938 for(int coordinate = 0; coordinate < 8; coordinate++)
939 {
940 for(int component = 0; component < 4; component++)
941 {
942 if(context->textureActive(coordinate, component))
943 {
944 state.texture[coordinate].component |= 1 << component;
945
946 if(point && !sprite)
947 {
948 state.texture[coordinate].flat |= 1 << component;
949 }
950 }
951 }
952
953 if(context->textureTransformProject[coordinate] && context->pixelShaderVersion() <= 0x0103)
954 {
955 if(context->textureTransformCount[coordinate] == 2)
956 {
957 state.texture[coordinate].project = 1;
958 }
959 else if(context->textureTransformCount[coordinate] == 3)
960 {
961 state.texture[coordinate].project = 2;
962 }
963 else if(context->textureTransformCount[coordinate] == 4 || context->textureTransformCount[coordinate] == 0)
964 {
965 state.texture[coordinate].project = 3;
966 }
967 }
968 }
969
970 for(int color = 0; color < 2; color++)
971 {
972 for(int component = 0; component < 4; component++)
973 {
974 if(context->colorActive(color, component))
975 {
976 state.color[color].component |= 1 << component;
977
978 if(point || flatShading)
979 {
980 state.color[color].flat |= 1 << component;
981 }
982 }
983 }
984 }
985
986 if(context->fogActive())
987 {
988 state.fog.component = true;
989
990 if(point)
991 {
992 state.fog.flat = true;
993 }
994 }
995 }
996 else
997 {
998 for(int interpolant = 0; interpolant < 10; interpolant++)
999 {
1000 for(int component = 0; component < 4; component++)
1001 {
1002 if(context->pixelShader->semantic[interpolant][component].active())
1003 {
1004 bool flat = point;
1005
1006 switch(context->pixelShader->semantic[interpolant][component].usage)
1007 {
John Bauman19bac1e2014-05-06 15:23:49 -04001008 case Shader::USAGE_TEXCOORD: flat = point && !sprite; break;
1009 case Shader::USAGE_COLOR: flat = flatShading; break;
John Bauman89401822014-05-06 15:04:28 -04001010 }
1011
1012 state.interpolant[interpolant].component |= 1 << component;
1013
1014 if(flat)
1015 {
1016 state.interpolant[interpolant].flat |= 1 << component;
1017 }
1018 }
1019 }
1020 }
1021 }
1022
1023 if(state.centroid)
1024 {
1025 for(int interpolant = 0; interpolant < 10; interpolant++)
1026 {
1027 for(int component = 0; component < 4; component++)
1028 {
1029 state.interpolant[interpolant].centroid = context->pixelShader->semantic[interpolant][0].centroid;
1030 }
1031 }
1032 }
1033
1034 state.hash = state.computeHash();
1035
1036 return state;
1037 }
1038
1039 Routine *PixelProcessor::routine(const State &state)
1040 {
1041 Routine *routine = routineCache->query(state);
1042
1043 if(!routine)
1044 {
1045 Rasterizer *generator = new QuadRasterizer(state, context->pixelShader);
1046 generator->generate();
1047 routine = generator->getRoutine();
1048 delete generator;
1049
1050 routineCache->add(state, routine);
1051 }
1052
1053 return routine;
1054 }
1055}